CFStrings for Darwin.
gcc: Based on the CFString implementation in FSF apple/trunk branch. * target.def (objc_construct_string): New Hook. * doc/tm.texi (objc_construct_string): Document. * doc/tm.texi.in (TARGET_OBJC_CONSTRUCT_STRING): New. * config/t-darwin: Amend build rules for darwin.o. * config/darwin.opt: Add cfstrings flags. * config/darwin-c.c: Define __CONSTANT_CFSTRINGS__. (darwin_objc_construct_string): New. * config/i386/darwin.h (SUBTARGET_INIT_BUILTINS): Define. * config/i386/i386.c (ix86_init_builtins): Add SUBTARGET_INIT_BUILTINS. * config/darwin-protos.h (darwin_init_cfstring_builtins): New prototype. (darwin_fold_builtin): Likewise. (darwin_build_constant_cfstring): Likewise. (darwin_objc_construct_string): Likewise. (darwin_cfstring_p): Likewise. (darwin_enter_string_into_cfstring_table): Likewise. * config/rs6000/darwin.h (SUBTARGET_INIT_BUILTINS) Update for CFString. * config/darwin.c (darwin_running_cxx): New var. (machopic_select_section): Return cfstring_constant_object_section. (darwin_override_options): Set darwin_running_cxx. (add_builtin_field_decl): New. (darwin_init_cfstring_builtins): New. (darwin_build_constant_cfstring): New. (darwin_fold_builtin): New. (cfstring_hash): New. (cfstring_eq): New. (darwin_enter_string_into_cfstring_table): New. * config/darwin-sections.def (cfstring_constant_object_section): New. * config/darwin.h (TARGET_FOLD_BUILTIN): Define. (TARGET_OBJC_CONSTRUCT_STRING): Define. gcc/objc: Based on the CFString implementation in FSF apple/trunk branch. * objc/objc-act.c (objc_build_string_object): Handle CFStrings. From-SVN: r165820
This commit is contained in:
parent
5e5db3b4b4
commit
2670598830
@ -1,3 +1,37 @@
|
||||
2010-10-21 Iain Sandoe <iains@gcc.gnu.org>
|
||||
|
||||
Based on the CFString implementation in FSF apple/trunk branch.
|
||||
|
||||
* target.def (objc_construct_string): New Hook.
|
||||
* doc/tm.texi (objc_construct_string): Document.
|
||||
* doc/tm.texi.in (TARGET_OBJC_CONSTRUCT_STRING): New.
|
||||
* config/t-darwin: Amend build rules for darwin.o.
|
||||
* config/darwin.opt: Add cfstrings flags.
|
||||
* config/darwin-c.c: Define __CONSTANT_CFSTRINGS__.
|
||||
(darwin_objc_construct_string): New.
|
||||
* config/i386/darwin.h (SUBTARGET_INIT_BUILTINS): Define.
|
||||
* config/i386/i386.c (ix86_init_builtins): Add SUBTARGET_INIT_BUILTINS.
|
||||
* config/darwin-protos.h (darwin_init_cfstring_builtins): New prototype.
|
||||
(darwin_fold_builtin): Likewise.
|
||||
(darwin_build_constant_cfstring): Likewise.
|
||||
(darwin_objc_construct_string): Likewise.
|
||||
(darwin_cfstring_p): Likewise.
|
||||
(darwin_enter_string_into_cfstring_table): Likewise.
|
||||
* config/rs6000/darwin.h (SUBTARGET_INIT_BUILTINS) Update for CFString.
|
||||
* config/darwin.c (darwin_running_cxx): New var.
|
||||
(machopic_select_section): Return cfstring_constant_object_section.
|
||||
(darwin_override_options): Set darwin_running_cxx.
|
||||
(add_builtin_field_decl): New.
|
||||
(darwin_init_cfstring_builtins): New.
|
||||
(darwin_build_constant_cfstring): New.
|
||||
(darwin_fold_builtin): New.
|
||||
(cfstring_hash): New.
|
||||
(cfstring_eq): New.
|
||||
(darwin_enter_string_into_cfstring_table): New.
|
||||
* config/darwin-sections.def (cfstring_constant_object_section): New.
|
||||
* config/darwin.h (TARGET_FOLD_BUILTIN): Define.
|
||||
(TARGET_OBJC_CONSTRUCT_STRING): Define.
|
||||
|
||||
2010-10-21 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
* config/alpha/alpha.c (alpha_build_builtin_va_list): Use
|
||||
|
@ -608,6 +608,9 @@ darwin_cpp_builtins (cpp_reader *pfile)
|
||||
to be defined and won't work if it isn't. */
|
||||
builtin_define_with_value ("__APPLE_CC__", "1", false);
|
||||
|
||||
if (darwin_constant_cfstrings)
|
||||
builtin_define ("__CONSTANT_CFSTRINGS__");
|
||||
|
||||
builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
|
||||
version_as_macro(), false);
|
||||
|
||||
@ -658,3 +661,20 @@ handle_c_option (size_t code,
|
||||
#define TARGET_HANDLE_C_OPTION handle_c_option
|
||||
|
||||
struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
|
||||
|
||||
/* Allow ObjC* access to CFStrings. */
|
||||
tree
|
||||
darwin_objc_construct_string (tree str)
|
||||
{
|
||||
if (!darwin_constant_cfstrings)
|
||||
{
|
||||
/* Even though we are not using CFStrings, place our literal
|
||||
into the cfstring_htab hash table, so that the
|
||||
darwin_constant_cfstring_p() function will see it. */
|
||||
darwin_enter_string_into_cfstring_table (str);
|
||||
/* Fall back to NSConstantString. */
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
return darwin_build_constant_cfstring (str);
|
||||
}
|
||||
|
@ -91,6 +91,14 @@ extern void darwin_asm_declare_constant_name (FILE *, const char *,
|
||||
const_tree, HOST_WIDE_INT);
|
||||
extern bool darwin_binds_local_p (const_tree);
|
||||
extern void darwin_cpp_builtins (struct cpp_reader *);
|
||||
|
||||
extern void darwin_init_cfstring_builtins (unsigned);
|
||||
extern tree darwin_fold_builtin (tree, int, tree *, bool);
|
||||
extern tree darwin_objc_construct_string (tree);
|
||||
extern bool darwin_cfstring_p (tree);
|
||||
extern tree darwin_build_constant_cfstring (tree str);
|
||||
extern void darwin_enter_string_into_cfstring_table (tree);
|
||||
|
||||
extern void darwin_asm_output_anchor (rtx symbol);
|
||||
extern bool darwin_kextabi_p (void);
|
||||
extern void darwin_override_options (void);
|
||||
|
@ -33,6 +33,9 @@ DEF_SECTION (cstring_section, SECTION_MERGE | SECTION_STRINGS, ".cstring", 0)
|
||||
DEF_SECTION (literal4_section, SECTION_MERGE, ".literal4", 0)
|
||||
DEF_SECTION (literal8_section, SECTION_MERGE, ".literal8", 0)
|
||||
DEF_SECTION (literal16_section, SECTION_MERGE, ".literal16", 0)
|
||||
/* Unlike constant NSStrings, constant CFStrings do not live in the __OBJC segment
|
||||
since they may also occur in pure C or C++ programs. */
|
||||
DEF_SECTION (cfstring_constant_object_section, 0, ".section __DATA, __cfstring", 0)
|
||||
DEF_SECTION (constructor_section, 0, ".constructor", 0)
|
||||
DEF_SECTION (mod_init_section, 0, ".mod_init_func", 0)
|
||||
DEF_SECTION (mod_term_section, 0, ".mod_term_func", 0)
|
||||
|
@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "langhooks.h"
|
||||
#include "target.h"
|
||||
#include "tm_p.h"
|
||||
#include "c-tree.h"
|
||||
#include "c-lang.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "toplev.h"
|
||||
#include "hashtab.h"
|
||||
@ -85,6 +87,11 @@ along with GCC; see the file COPYING3. If not see
|
||||
kernel) the stubs might still be required, and this will be set true. */
|
||||
int darwin_emit_branch_islands = false;
|
||||
|
||||
/* A flag to determine whether we are running c++ or obj-c++. This has to be
|
||||
settable from non-c-family contexts too (i.e. we can't use the c_dialect_
|
||||
functions). */
|
||||
int darwin_running_cxx;
|
||||
|
||||
/* Section names. */
|
||||
section * darwin_sections[NUM_DARWIN_SECTIONS];
|
||||
|
||||
@ -1256,6 +1263,8 @@ machopic_select_section (tree decl,
|
||||
else
|
||||
return darwin_sections[objc_string_object_section];
|
||||
}
|
||||
else if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_CFString"))
|
||||
return darwin_sections[cfstring_constant_object_section];
|
||||
else
|
||||
return base_section;
|
||||
}
|
||||
@ -1910,6 +1919,9 @@ darwin_override_options (void)
|
||||
if (darwin_macosx_version_min
|
||||
&& strverscmp (darwin_macosx_version_min, "10.5") < 0)
|
||||
darwin_emit_branch_islands = true;
|
||||
|
||||
/* The c_dialect...() macros are not available to us here. */
|
||||
darwin_running_cxx = (strstr (lang_hooks.name, "C++") != 0);
|
||||
}
|
||||
|
||||
/* Add $LDBL128 suffix to long double builtins. */
|
||||
@ -1954,5 +1966,307 @@ darwin_patch_builtins (void)
|
||||
#undef PATCH_BUILTIN_VARIADIC
|
||||
}
|
||||
|
||||
/* CFStrings implementation. */
|
||||
static GTY(()) tree cfstring_class_reference = NULL_TREE;
|
||||
static GTY(()) tree cfstring_type_node = NULL_TREE;
|
||||
static GTY(()) tree ccfstring_type_node = NULL_TREE;
|
||||
static GTY(()) tree pccfstring_type_node = NULL_TREE;
|
||||
static GTY(()) tree pcint_type_node = NULL_TREE;
|
||||
static GTY(()) tree pcchar_type_node = NULL_TREE;
|
||||
|
||||
static enum built_in_function DARWIN_BUILTIN_CFSTRINGMAKECONSTANTSTRING;
|
||||
|
||||
/* Store all constructed constant CFStrings in a hash table so that
|
||||
they get uniqued properly. */
|
||||
|
||||
typedef struct GTY (()) cfstring_descriptor {
|
||||
/* The string literal. */
|
||||
tree literal;
|
||||
/* The resulting constant CFString. */
|
||||
tree constructor;
|
||||
} cfstring_descriptor;
|
||||
|
||||
static GTY ((param_is (struct cfstring_descriptor))) htab_t cfstring_htab;
|
||||
|
||||
static hashval_t cfstring_hash (const void *);
|
||||
static int cfstring_eq (const void *, const void *);
|
||||
|
||||
static tree
|
||||
add_builtin_field_decl (tree type, const char *name, tree **chain)
|
||||
{
|
||||
tree field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
get_identifier (name), type);
|
||||
|
||||
if (*chain != NULL)
|
||||
**chain = field;
|
||||
*chain = &DECL_CHAIN (field);
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
void
|
||||
darwin_init_cfstring_builtins (unsigned first_avail)
|
||||
{
|
||||
tree cfsfun, fields, pccfstring_ftype_pcchar;
|
||||
tree *chain = NULL;
|
||||
|
||||
DARWIN_BUILTIN_CFSTRINGMAKECONSTANTSTRING =
|
||||
(enum built_in_function) first_avail;
|
||||
|
||||
/* struct __builtin_CFString {
|
||||
const int *isa; (will point at
|
||||
int flags; __CFConstantStringClassReference)
|
||||
const char *str;
|
||||
long length;
|
||||
}; */
|
||||
|
||||
pcint_type_node = build_pointer_type
|
||||
(build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
|
||||
|
||||
pcchar_type_node = build_pointer_type
|
||||
(build_qualified_type (char_type_node, TYPE_QUAL_CONST));
|
||||
|
||||
cfstring_type_node = (*lang_hooks.types.make_type) (RECORD_TYPE);
|
||||
|
||||
/* Have to build backwards for finish struct. */
|
||||
fields = add_builtin_field_decl (long_integer_type_node, "length", &chain);
|
||||
add_builtin_field_decl (pcchar_type_node, "str", &chain);
|
||||
add_builtin_field_decl (integer_type_node, "flags", &chain);
|
||||
add_builtin_field_decl (pcint_type_node, "isa", &chain);
|
||||
finish_builtin_struct (cfstring_type_node, "__builtin_CFString",
|
||||
fields, NULL_TREE);
|
||||
|
||||
/* const struct __builtin_CFstring *
|
||||
__builtin___CFStringMakeConstantString (const char *); */
|
||||
|
||||
ccfstring_type_node = build_qualified_type
|
||||
(cfstring_type_node, TYPE_QUAL_CONST);
|
||||
pccfstring_type_node = build_pointer_type (ccfstring_type_node);
|
||||
pccfstring_ftype_pcchar = build_function_type_list
|
||||
(pccfstring_type_node, pcchar_type_node, NULL_TREE);
|
||||
|
||||
cfsfun = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
|
||||
get_identifier ("__builtin___CFStringMakeConstantString"),
|
||||
pccfstring_ftype_pcchar);
|
||||
|
||||
TREE_PUBLIC (cfsfun) = 1;
|
||||
DECL_EXTERNAL (cfsfun) = 1;
|
||||
DECL_ARTIFICIAL (cfsfun) = 1;
|
||||
/* Make a lang-specific section - dup_lang_specific_decl makes a new node
|
||||
in place of the existing, which may be NULL. */
|
||||
DECL_LANG_SPECIFIC (cfsfun) = NULL;
|
||||
(*lang_hooks.dup_lang_specific_decl) (cfsfun);
|
||||
DECL_BUILT_IN_CLASS (cfsfun) = BUILT_IN_MD;
|
||||
DECL_FUNCTION_CODE (cfsfun) = DARWIN_BUILTIN_CFSTRINGMAKECONSTANTSTRING;
|
||||
lang_hooks.builtin_function (cfsfun);
|
||||
|
||||
/* extern int __CFConstantStringClassReference[]; */
|
||||
cfstring_class_reference = build_decl (BUILTINS_LOCATION, VAR_DECL,
|
||||
get_identifier ("__CFConstantStringClassReference"),
|
||||
build_array_type (integer_type_node, NULL_TREE));
|
||||
|
||||
TREE_PUBLIC (cfstring_class_reference) = 1;
|
||||
DECL_ARTIFICIAL (cfstring_class_reference) = 1;
|
||||
(*lang_hooks.decls.pushdecl) (cfstring_class_reference);
|
||||
DECL_EXTERNAL (cfstring_class_reference) = 1;
|
||||
rest_of_decl_compilation (cfstring_class_reference, 0, 0);
|
||||
|
||||
/* Initialize the hash table used to hold the constant CFString objects. */
|
||||
cfstring_htab = htab_create_ggc (31, cfstring_hash, cfstring_eq, NULL);
|
||||
}
|
||||
|
||||
tree
|
||||
darwin_fold_builtin (tree fndecl, int n_args, tree *argp,
|
||||
bool ARG_UNUSED (ignore))
|
||||
{
|
||||
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
|
||||
|
||||
if (fcode == DARWIN_BUILTIN_CFSTRINGMAKECONSTANTSTRING)
|
||||
{
|
||||
if (!darwin_constant_cfstrings)
|
||||
{
|
||||
error ("built-in function %qD requires the"
|
||||
" %<-mconstant-cfstrings%> flag", fndecl);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (n_args != 1)
|
||||
{
|
||||
error ("built-in function %qD takes one argument only", fndecl);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return darwin_build_constant_cfstring (*argp);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
cfstring_hash (const void *ptr)
|
||||
{
|
||||
tree str = ((const struct cfstring_descriptor *)ptr)->literal;
|
||||
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
|
||||
int i, len = TREE_STRING_LENGTH (str);
|
||||
hashval_t h = len;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
h = ((h * 613) + p[i]);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
cfstring_eq (const void *ptr1, const void *ptr2)
|
||||
{
|
||||
tree str1 = ((const struct cfstring_descriptor *)ptr1)->literal;
|
||||
tree str2 = ((const struct cfstring_descriptor *)ptr2)->literal;
|
||||
int len1 = TREE_STRING_LENGTH (str1);
|
||||
|
||||
return (len1 == TREE_STRING_LENGTH (str2)
|
||||
&& !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
|
||||
len1));
|
||||
}
|
||||
|
||||
tree
|
||||
darwin_build_constant_cfstring (tree str)
|
||||
{
|
||||
struct cfstring_descriptor *desc, key;
|
||||
void **loc;
|
||||
tree addr;
|
||||
|
||||
if (!str)
|
||||
{
|
||||
error ("CFString literal is missing");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
STRIP_NOPS (str);
|
||||
|
||||
if (TREE_CODE (str) == ADDR_EXPR)
|
||||
str = TREE_OPERAND (str, 0);
|
||||
|
||||
if (TREE_CODE (str) != STRING_CST)
|
||||
{
|
||||
error ("CFString literal expression is not a string constant");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Perhaps we already constructed a constant CFString just like this one? */
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, INSERT);
|
||||
desc = (struct cfstring_descriptor *) *loc;
|
||||
|
||||
if (!desc)
|
||||
{
|
||||
tree var, constructor, field;
|
||||
VEC(constructor_elt,gc) *v = NULL;
|
||||
int length = TREE_STRING_LENGTH (str) - 1;
|
||||
|
||||
if (darwin_warn_nonportable_cfstrings)
|
||||
{
|
||||
const char *s = TREE_STRING_POINTER (str);
|
||||
int l = 0;
|
||||
|
||||
for (l = 0; l < length; l++)
|
||||
if (!s[l] || !isascii (s[l]))
|
||||
{
|
||||
warning (darwin_warn_nonportable_cfstrings, "%s in CFString literal",
|
||||
s[l] ? "non-ASCII character" : "embedded NUL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*loc = desc = ggc_alloc_cleared_cfstring_descriptor ();
|
||||
desc->literal = str;
|
||||
|
||||
/* isa *. */
|
||||
field = TYPE_FIELDS (ccfstring_type_node);
|
||||
CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
|
||||
build1 (ADDR_EXPR, TREE_TYPE (field),
|
||||
cfstring_class_reference));
|
||||
/* flags */
|
||||
field = DECL_CHAIN (field);
|
||||
CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
|
||||
build_int_cst (TREE_TYPE (field), 0x000007c8));
|
||||
/* string *. */
|
||||
field = DECL_CHAIN (field);
|
||||
CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
|
||||
build1 (ADDR_EXPR, TREE_TYPE (field), str));
|
||||
/* length */
|
||||
field = DECL_CHAIN (field);
|
||||
CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
|
||||
build_int_cst (TREE_TYPE (field), length));
|
||||
|
||||
constructor = build_constructor (ccfstring_type_node, v);
|
||||
TREE_READONLY (constructor) = 1;
|
||||
TREE_CONSTANT (constructor) = 1;
|
||||
TREE_STATIC (constructor) = 1;
|
||||
|
||||
/* Fromage: The C++ flavor of 'build_unary_op' expects constructor nodes
|
||||
to have the TREE_HAS_CONSTRUCTOR (...) bit set. However, this file is
|
||||
being built without any knowledge of C++ tree accessors; hence, we shall
|
||||
use the generic accessor that TREE_HAS_CONSTRUCTOR actually maps to! */
|
||||
if (darwin_running_cxx)
|
||||
TREE_LANG_FLAG_4 (constructor) = 1; /* TREE_HAS_CONSTRUCTOR */
|
||||
|
||||
/* Create an anonymous global variable for this CFString. */
|
||||
var = build_decl (input_location, CONST_DECL,
|
||||
NULL, TREE_TYPE (constructor));
|
||||
DECL_ARTIFICIAL (var) = 1;
|
||||
TREE_STATIC (var) = 1;
|
||||
DECL_INITIAL (var) = constructor;
|
||||
/* FIXME: This should use a translation_unit_decl to indicate file scope. */
|
||||
DECL_CONTEXT (var) = NULL_TREE;
|
||||
desc->constructor = var;
|
||||
}
|
||||
|
||||
addr = build1 (ADDR_EXPR, pccfstring_type_node, desc->constructor);
|
||||
TREE_CONSTANT (addr) = 1;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool
|
||||
darwin_cfstring_p (tree str)
|
||||
{
|
||||
struct cfstring_descriptor key;
|
||||
void **loc;
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
STRIP_NOPS (str);
|
||||
|
||||
if (TREE_CODE (str) == ADDR_EXPR)
|
||||
str = TREE_OPERAND (str, 0);
|
||||
|
||||
if (TREE_CODE (str) != STRING_CST)
|
||||
return false;
|
||||
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, NO_INSERT);
|
||||
|
||||
if (loc)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
darwin_enter_string_into_cfstring_table (tree str)
|
||||
{
|
||||
struct cfstring_descriptor key;
|
||||
void **loc;
|
||||
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, INSERT);
|
||||
|
||||
if (!*loc)
|
||||
{
|
||||
*loc = ggc_alloc_cleared_cfstring_descriptor ();
|
||||
((struct cfstring_descriptor *)*loc)->literal = str;
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-darwin.h"
|
||||
|
@ -1054,6 +1054,12 @@ __enable_execute_stack (void *addr) \
|
||||
#define TARGET_CXX_CDTOR_RETURNS_THIS (darwin_kextabi_p)
|
||||
#define TARGET_KEXTABI flag_apple_kext
|
||||
|
||||
/* We have target-specific builtins. */
|
||||
#define TARGET_FOLD_BUILTIN darwin_fold_builtin
|
||||
|
||||
#define TARGET_OBJC_CONSTRUCT_STRING \
|
||||
darwin_objc_construct_string
|
||||
|
||||
#define TARGET_HAS_TARGETCM 1
|
||||
|
||||
#ifndef CROSS_DIRECTORY_STRUCTURE
|
||||
|
@ -18,6 +18,14 @@
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
mconstant-cfstrings
|
||||
Target Report Var(darwin_constant_cfstrings) Init(1)
|
||||
Generate compile-time CFString objects
|
||||
|
||||
Wnonportable-cfstrings
|
||||
Target Report Var(darwin_warn_nonportable_cfstrings) Init(1) Warning
|
||||
Warn if constant CFString objects contain non-portable characters
|
||||
|
||||
mfix-and-continue
|
||||
Target Report Var(darwin_fix_and_continue)
|
||||
Generate code suitable for fast turn around debugging
|
||||
|
@ -314,3 +314,10 @@ extern int darwin_emit_branch_islands;
|
||||
#define MACHO_SYMBOL_FLAG_VARIABLE ((SYMBOL_FLAG_MACH_DEP) << 3)
|
||||
|
||||
#define SUBTARGET32_DEFAULT_CPU "i686"
|
||||
|
||||
#undef SUBTARGET_INIT_BUILTINS
|
||||
#define SUBTARGET_INIT_BUILTINS \
|
||||
do { \
|
||||
darwin_init_cfstring_builtins ((unsigned) (IX86_BUILTIN_MAX));\
|
||||
} while(0)
|
||||
|
||||
|
@ -24410,6 +24410,10 @@ ix86_init_builtins (void)
|
||||
|
||||
if (TARGET_64BIT)
|
||||
ix86_init_builtins_va_builtins_abi ();
|
||||
|
||||
#ifdef SUBTARGET_INIT_BUILTINS
|
||||
SUBTARGET_INIT_BUILTINS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the ix86 builtin for CODE. */
|
||||
|
@ -436,5 +436,10 @@ extern int darwin_emit_branch_islands;
|
||||
default, as kernel code doesn't save/restore those registers. */
|
||||
#define OS_MISSING_ALTIVEC (flag_mkernel || flag_apple_kext)
|
||||
|
||||
/* Darwin has to rename some of the long double builtins. */
|
||||
#define SUBTARGET_INIT_BUILTINS darwin_patch_builtins ()
|
||||
/* PPC Darwin has to rename some of the long double builtins. */
|
||||
#undef SUBTARGET_INIT_BUILTINS
|
||||
#define SUBTARGET_INIT_BUILTINS \
|
||||
do { \
|
||||
darwin_patch_builtins (); \
|
||||
darwin_init_cfstring_builtins ((unsigned) (RS6000_BUILTIN_COUNT)); \
|
||||
} while(0)
|
||||
|
@ -21,7 +21,7 @@ darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(REAL_H) insn-config.h \
|
||||
conditions.h insn-flags.h output.h insn-attr.h flags.h $(TREE_H) expr.h \
|
||||
reload.h function.h $(GGC_H) langhooks.h $(TARGET_H) $(TM_P_H) gt-darwin.h \
|
||||
config/darwin-sections.def
|
||||
c-tree.h c-lang.h config/darwin-sections.def
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||
$(srcdir)/config/darwin.c
|
||||
|
||||
|
@ -757,6 +757,10 @@ only available in the C (and related language) front ends, then you
|
||||
should use @code{TARGET_HANDLE_C_OPTION} instead.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} tree TARGET_OBJC_CONSTRUCT_STRING (tree @var{string})
|
||||
Construct a constant string representation for @var{string}
|
||||
@end deftypefn
|
||||
|
||||
@defmac TARGET_VERSION
|
||||
This macro is a C statement to print on @code{stderr} a string
|
||||
describing the particular machine description choice. Every machine
|
||||
|
@ -757,6 +757,8 @@ only available in the C (and related language) front ends, then you
|
||||
should use @code{TARGET_HANDLE_C_OPTION} instead.
|
||||
@end deftypefn
|
||||
|
||||
@hook TARGET_OBJC_CONSTRUCT_STRING
|
||||
|
||||
@defmac TARGET_VERSION
|
||||
This macro is a C statement to print on @code{stderr} a string
|
||||
describing the particular machine description choice. Every machine
|
||||
|
@ -1,3 +1,9 @@
|
||||
2010-10-21 Iain Sandoe <iains@gcc.gnu.org>
|
||||
|
||||
Based on the CFString implementation in FSF apple/trunk branch.
|
||||
|
||||
* objc/objc-act.c (objc_build_string_object): Handle CFStrings.
|
||||
|
||||
2010-10-21 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc-act.c (get_objc_string_decl): Use a switch instead of a
|
||||
|
@ -2576,7 +2576,7 @@ string_eq (const void *ptr1, const void *ptr2)
|
||||
tree
|
||||
objc_build_string_object (tree string)
|
||||
{
|
||||
tree constructor = NULL_TREE, constant_string_class;
|
||||
tree constant_string_class;
|
||||
int length;
|
||||
tree fields, addr;
|
||||
struct string_descriptor *desc, key;
|
||||
@ -2587,6 +2587,17 @@ objc_build_string_object (tree string)
|
||||
TREE_SET_CODE (string, STRING_CST);
|
||||
length = TREE_STRING_LENGTH (string) - 1;
|
||||
|
||||
/* The target may have different ideas on how to construct an ObjC string
|
||||
literal. On Darwin (Mac OS X), for example, we may wish to obtain a
|
||||
constant CFString reference instead.
|
||||
At present, this is only supported for the NeXT runtime. */
|
||||
if (flag_next_runtime && targetcm.objc_construct_string)
|
||||
{
|
||||
tree constructor = (*targetcm.objc_construct_string) (string);
|
||||
if (constructor)
|
||||
return build1 (NOP_EXPR, objc_object_type, constructor);
|
||||
}
|
||||
|
||||
/* Check whether the string class being used actually exists and has the
|
||||
correct ivar layout. */
|
||||
if (!string_layout_checked)
|
||||
@ -2626,7 +2637,7 @@ objc_build_string_object (tree string)
|
||||
|
||||
if (!desc)
|
||||
{
|
||||
tree var;
|
||||
tree var, constructor;
|
||||
VEC(constructor_elt,gc) *v = NULL;
|
||||
*loc = desc = ggc_alloc_string_descriptor ();
|
||||
desc->literal = string;
|
||||
|
@ -2542,4 +2542,10 @@ DEFHOOK
|
||||
bool, (size_t code, const char *arg, int value),
|
||||
default_handle_c_option)
|
||||
|
||||
DEFHOOK
|
||||
(objc_construct_string,
|
||||
"Construct a constant string representation for @var{string}",
|
||||
tree, (tree string),
|
||||
NULL)
|
||||
|
||||
HOOK_VECTOR_END (C90_EMPTY_HACK)
|
||||
|
Loading…
Reference in New Issue
Block a user