]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/darwin-c.c
2015-06-17 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / darwin-c.c
1 /* Darwin support needed only by C/C++ frontends.
2 Copyright (C) 2001-2015 Free Software Foundation, Inc.
3 Contributed by Apple Computer Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "cpplib.h"
26 #include "alias.h"
27 #include "symtab.h"
28 #include "tree.h"
29 #include "target.h"
30 #include "incpath.h"
31 #include "c-family/c-common.h"
32 #include "c-family/c-pragma.h"
33 #include "c-family/c-format.h"
34 #include "diagnostic-core.h"
35 #include "flags.h"
36 #include "tm_p.h"
37 #include "cppdefault.h"
38 #include "prefix.h"
39 #include "c-family/c-target.h"
40 #include "c-family/c-target-def.h"
41 #include "predict.h"
42 #include "dominance.h"
43 #include "cfg.h"
44 #include "cfgrtl.h"
45 #include "cfganal.h"
46 #include "lcm.h"
47 #include "cfgbuild.h"
48 #include "cfgcleanup.h"
49 #include "basic-block.h"
50 #include "plugin-api.h"
51 #include "hard-reg-set.h"
52 #include "function.h"
53 #include "ipa-ref.h"
54 #include "cgraph.h"
55 #include "../../libcpp/internal.h"
56
57 /* Pragmas. */
58
59 #define BAD(gmsgid) do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
60 #define BAD2(msgid, arg) do { warning (OPT_Wpragmas, msgid, arg); return; } while (0)
61
62 static bool using_frameworks = false;
63
64 static const char *find_subframework_header (cpp_reader *pfile, const char *header,
65 cpp_dir **dirp);
66
67 typedef struct align_stack
68 {
69 int alignment;
70 struct align_stack * prev;
71 } align_stack;
72
73 static struct align_stack * field_align_stack = NULL;
74
75 /* Maintain a small stack of alignments. This is similar to pragma
76 pack's stack, but simpler. */
77
78 static void
79 push_field_alignment (int bit_alignment)
80 {
81 align_stack *entry = XNEW (align_stack);
82
83 entry->alignment = maximum_field_alignment;
84 entry->prev = field_align_stack;
85 field_align_stack = entry;
86
87 maximum_field_alignment = bit_alignment;
88 }
89
90 static void
91 pop_field_alignment (void)
92 {
93 if (field_align_stack)
94 {
95 align_stack *entry = field_align_stack;
96
97 maximum_field_alignment = entry->alignment;
98 field_align_stack = entry->prev;
99 free (entry);
100 }
101 else
102 error ("too many #pragma options align=reset");
103 }
104
105 /* Handlers for Darwin-specific pragmas. */
106
107 void
108 darwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
109 {
110 /* Do nothing. */
111 }
112
113 /* #pragma options align={mac68k|power|reset} */
114
115 void
116 darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
117 {
118 const char *arg;
119 tree t, x;
120
121 if (pragma_lex (&t) != CPP_NAME)
122 BAD ("malformed '#pragma options', ignoring");
123 arg = IDENTIFIER_POINTER (t);
124 if (strcmp (arg, "align"))
125 BAD ("malformed '#pragma options', ignoring");
126 if (pragma_lex (&t) != CPP_EQ)
127 BAD ("malformed '#pragma options', ignoring");
128 if (pragma_lex (&t) != CPP_NAME)
129 BAD ("malformed '#pragma options', ignoring");
130
131 if (pragma_lex (&x) != CPP_EOF)
132 warning (OPT_Wpragmas, "junk at end of '#pragma options'");
133
134 arg = IDENTIFIER_POINTER (t);
135 if (!strcmp (arg, "mac68k"))
136 push_field_alignment (16);
137 else if (!strcmp (arg, "power"))
138 push_field_alignment (0);
139 else if (!strcmp (arg, "reset"))
140 pop_field_alignment ();
141 else
142 BAD ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
143 }
144
145 /* #pragma unused ([var {, var}*]) */
146
147 void
148 darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
149 {
150 tree decl, x;
151 int tok;
152
153 if (pragma_lex (&x) != CPP_OPEN_PAREN)
154 BAD ("missing '(' after '#pragma unused', ignoring");
155
156 while (1)
157 {
158 tok = pragma_lex (&decl);
159 if (tok == CPP_NAME && decl)
160 {
161 tree local = lookup_name (decl);
162 if (local && (TREE_CODE (local) == PARM_DECL
163 || TREE_CODE (local) == VAR_DECL))
164 {
165 TREE_USED (local) = 1;
166 DECL_READ_P (local) = 1;
167 }
168 tok = pragma_lex (&x);
169 if (tok != CPP_COMMA)
170 break;
171 }
172 }
173
174 if (tok != CPP_CLOSE_PAREN)
175 BAD ("missing ')' after '#pragma unused', ignoring");
176
177 if (pragma_lex (&x) != CPP_EOF)
178 BAD ("junk at end of '#pragma unused'");
179 }
180
181 /* Parse the ms_struct pragma. */
182 void
183 darwin_pragma_ms_struct (cpp_reader *pfile ATTRIBUTE_UNUSED)
184 {
185 const char *arg;
186 tree t;
187
188 if (pragma_lex (&t) != CPP_NAME)
189 BAD ("malformed '#pragma ms_struct', ignoring");
190 arg = IDENTIFIER_POINTER (t);
191
192 if (!strcmp (arg, "on"))
193 darwin_ms_struct = true;
194 else if (!strcmp (arg, "off") || !strcmp (arg, "reset"))
195 darwin_ms_struct = false;
196 else
197 BAD ("malformed '#pragma ms_struct {on|off|reset}', ignoring");
198
199 if (pragma_lex (&t) != CPP_EOF)
200 BAD ("junk at end of '#pragma ms_struct'");
201 }
202
203 static struct frameworks_in_use {
204 size_t len;
205 const char *name;
206 cpp_dir* dir;
207 } *frameworks_in_use;
208 static int num_frameworks = 0;
209 static int max_frameworks = 0;
210
211
212 /* Remember which frameworks have been seen, so that we can ensure
213 that all uses of that framework come from the same framework. DIR
214 is the place where the named framework NAME, which is of length
215 LEN, was found. We copy the directory name from NAME, as it will be
216 freed by others. */
217
218 static void
219 add_framework (const char *name, size_t len, cpp_dir *dir)
220 {
221 char *dir_name;
222 int i;
223 for (i = 0; i < num_frameworks; ++i)
224 {
225 if (len == frameworks_in_use[i].len
226 && strncmp (name, frameworks_in_use[i].name, len) == 0)
227 {
228 return;
229 }
230 }
231 if (i >= max_frameworks)
232 {
233 max_frameworks = i*2;
234 max_frameworks += i == 0;
235 frameworks_in_use = XRESIZEVEC (struct frameworks_in_use,
236 frameworks_in_use, max_frameworks);
237 }
238 dir_name = XNEWVEC (char, len + 1);
239 memcpy (dir_name, name, len);
240 dir_name[len] = '\0';
241 frameworks_in_use[num_frameworks].name = dir_name;
242 frameworks_in_use[num_frameworks].len = len;
243 frameworks_in_use[num_frameworks].dir = dir;
244 ++num_frameworks;
245 }
246
247 /* Recall if we have seen the named framework NAME, before, and where
248 we saw it. NAME is LEN bytes long. The return value is the place
249 where it was seen before. */
250
251 static struct cpp_dir*
252 find_framework (const char *name, size_t len)
253 {
254 int i;
255 for (i = 0; i < num_frameworks; ++i)
256 {
257 if (len == frameworks_in_use[i].len
258 && strncmp (name, frameworks_in_use[i].name, len) == 0)
259 {
260 return frameworks_in_use[i].dir;
261 }
262 }
263 return 0;
264 }
265
266 /* There are two directories in a framework that contain header files,
267 Headers and PrivateHeaders. We search Headers first as it is more
268 common to upgrade a header from PrivateHeaders to Headers and when
269 that is done, the old one might hang around and be out of data,
270 causing grief. */
271
272 struct framework_header {const char * dirName; int dirNameLen; };
273 static struct framework_header framework_header_dirs[] = {
274 { "Headers", 7 },
275 { "PrivateHeaders", 14 },
276 { NULL, 0 }
277 };
278
279 /* Returns a pointer to a malloced string that contains the real pathname
280 to the file, given the base name and the name. */
281
282 static char *
283 framework_construct_pathname (const char *fname, cpp_dir *dir)
284 {
285 const char *buf;
286 size_t fname_len, frname_len;
287 cpp_dir *fast_dir;
288 char *frname;
289 struct stat st;
290 int i;
291
292 /* Framework names must have a / in them. */
293 buf = strchr (fname, '/');
294 if (buf)
295 fname_len = buf - fname;
296 else
297 return 0;
298
299 fast_dir = find_framework (fname, fname_len);
300
301 /* Framework includes must all come from one framework. */
302 if (fast_dir && dir != fast_dir)
303 return 0;
304
305 frname = XNEWVEC (char, strlen (fname) + dir->len + 2
306 + strlen(".framework/") + strlen("PrivateHeaders"));
307 strncpy (&frname[0], dir->name, dir->len);
308 frname_len = dir->len;
309 if (frname_len && frname[frname_len-1] != '/')
310 frname[frname_len++] = '/';
311 strncpy (&frname[frname_len], fname, fname_len);
312 frname_len += fname_len;
313 strncpy (&frname[frname_len], ".framework/", strlen (".framework/"));
314 frname_len += strlen (".framework/");
315
316 if (fast_dir == 0)
317 {
318 frname[frname_len-1] = 0;
319 if (stat (frname, &st) == 0)
320 {
321 /* As soon as we find the first instance of the framework,
322 we stop and never use any later instance of that
323 framework. */
324 add_framework (fname, fname_len, dir);
325 }
326 else
327 {
328 /* If we can't find the parent directory, no point looking
329 further. */
330 free (frname);
331 return 0;
332 }
333 frname[frname_len-1] = '/';
334 }
335
336 /* Append framework_header_dirs and header file name */
337 for (i = 0; framework_header_dirs[i].dirName; i++)
338 {
339 strncpy (&frname[frname_len],
340 framework_header_dirs[i].dirName,
341 framework_header_dirs[i].dirNameLen);
342 strcpy (&frname[frname_len + framework_header_dirs[i].dirNameLen],
343 &fname[fname_len]);
344
345 if (stat (frname, &st) == 0)
346 return frname;
347 }
348
349 free (frname);
350 return 0;
351 }
352
353 /* Search for FNAME in sub-frameworks. pname is the context that we
354 wish to search in. Return the path the file was found at,
355 otherwise return 0. */
356
357 static const char*
358 find_subframework_file (const char *fname, const char *pname)
359 {
360 char *sfrname;
361 const char *dot_framework = ".framework/";
362 const char *bufptr;
363 int sfrname_len, i, fname_len;
364 struct cpp_dir *fast_dir;
365 static struct cpp_dir subframe_dir;
366 struct stat st;
367
368 bufptr = strchr (fname, '/');
369
370 /* Subframework files must have / in the name. */
371 if (bufptr == 0)
372 return 0;
373
374 fname_len = bufptr - fname;
375 fast_dir = find_framework (fname, fname_len);
376
377 /* Sub framework header filename includes parent framework name and
378 header name in the "CarbonCore/OSUtils.h" form. If it does not
379 include slash it is not a sub framework include. */
380 bufptr = strstr (pname, dot_framework);
381
382 /* If the parent header is not of any framework, then this header
383 cannot be part of any subframework. */
384 if (!bufptr)
385 return 0;
386
387 /* Now translate. For example, +- bufptr
388 fname = CarbonCore/OSUtils.h |
389 pname = /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
390 into
391 sfrname = /System/Library/Frameworks/Foundation.framework/Frameworks/CarbonCore.framework/Headers/OSUtils.h */
392
393 sfrname = XNEWVEC (char, strlen (pname) + strlen (fname) + 2 +
394 strlen ("Frameworks/") + strlen (".framework/")
395 + strlen ("PrivateHeaders"));
396
397 bufptr += strlen (dot_framework);
398
399 sfrname_len = bufptr - pname;
400
401 strncpy (&sfrname[0], pname, sfrname_len);
402
403 strncpy (&sfrname[sfrname_len], "Frameworks/", strlen ("Frameworks/"));
404 sfrname_len += strlen("Frameworks/");
405
406 strncpy (&sfrname[sfrname_len], fname, fname_len);
407 sfrname_len += fname_len;
408
409 strncpy (&sfrname[sfrname_len], ".framework/", strlen (".framework/"));
410 sfrname_len += strlen (".framework/");
411
412 /* Append framework_header_dirs and header file name */
413 for (i = 0; framework_header_dirs[i].dirName; i++)
414 {
415 strncpy (&sfrname[sfrname_len],
416 framework_header_dirs[i].dirName,
417 framework_header_dirs[i].dirNameLen);
418 strcpy (&sfrname[sfrname_len + framework_header_dirs[i].dirNameLen],
419 &fname[fname_len]);
420
421 if (stat (sfrname, &st) == 0)
422 {
423 if (fast_dir != &subframe_dir)
424 {
425 if (fast_dir)
426 warning (0, "subframework include %s conflicts with framework include",
427 fname);
428 else
429 add_framework (fname, fname_len, &subframe_dir);
430 }
431
432 return sfrname;
433 }
434 }
435 free (sfrname);
436
437 return 0;
438 }
439
440 /* Add PATH to the system includes. PATH must be malloc-ed and
441 NUL-terminated. System framework paths are C++ aware. */
442
443 static void
444 add_system_framework_path (char *path)
445 {
446 int cxx_aware = 1;
447 cpp_dir *p;
448
449 p = XNEW (cpp_dir);
450 p->next = NULL;
451 p->name = path;
452 p->sysp = 1 + !cxx_aware;
453 p->construct = framework_construct_pathname;
454 using_frameworks = 1;
455
456 add_cpp_dir_path (p, SYSTEM);
457 }
458
459 /* Add PATH to the bracket includes. PATH must be malloc-ed and
460 NUL-terminated. */
461
462 void
463 add_framework_path (char *path)
464 {
465 cpp_dir *p;
466
467 p = XNEW (cpp_dir);
468 p->next = NULL;
469 p->name = path;
470 p->sysp = 0;
471 p->construct = framework_construct_pathname;
472 using_frameworks = 1;
473
474 add_cpp_dir_path (p, BRACKET);
475 }
476
477 static const char *framework_defaults [] =
478 {
479 "/System/Library/Frameworks",
480 "/Library/Frameworks",
481 };
482
483 /* Register the GNU objective-C runtime include path if STDINC. */
484
485 void
486 darwin_register_objc_includes (const char *sysroot, const char *iprefix,
487 int stdinc)
488 {
489 const char *fname;
490 size_t len;
491 /* We do not do anything if we do not want the standard includes. */
492 if (!stdinc)
493 return;
494
495 fname = GCC_INCLUDE_DIR "-gnu-runtime";
496
497 /* Register the GNU OBJC runtime include path if we are compiling OBJC
498 with GNU-runtime. */
499
500 if (c_dialect_objc () && !flag_next_runtime)
501 {
502 char *str;
503 /* See if our directory starts with the standard prefix.
504 "Translate" them, i.e. replace /usr/local/lib/gcc... with
505 IPREFIX and search them first. */
506 if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0 && !sysroot
507 && !strncmp (fname, cpp_GCC_INCLUDE_DIR, len))
508 {
509 str = concat (iprefix, fname + len, NULL);
510 /* FIXME: wrap the headers for C++awareness. */
511 add_path (str, SYSTEM, /*c++aware=*/false, false);
512 }
513
514 /* Should this directory start with the sysroot? */
515 if (sysroot)
516 str = concat (sysroot, fname, NULL);
517 else
518 str = update_path (fname, "");
519
520 add_path (str, SYSTEM, /*c++aware=*/false, false);
521 }
522 }
523
524
525 /* Register all the system framework paths if STDINC is true and setup
526 the missing_header callback for subframework searching if any
527 frameworks had been registered. */
528
529 void
530 darwin_register_frameworks (const char *sysroot,
531 const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
532 {
533 if (stdinc)
534 {
535 size_t i;
536
537 /* Setup default search path for frameworks. */
538 for (i=0; i<sizeof (framework_defaults)/sizeof(const char *); ++i)
539 {
540 char *str;
541 if (sysroot)
542 str = concat (sysroot, xstrdup (framework_defaults [i]), NULL);
543 else
544 str = xstrdup (framework_defaults[i]);
545 /* System Framework headers are cxx aware. */
546 add_system_framework_path (str);
547 }
548 }
549
550 if (using_frameworks)
551 cpp_get_callbacks (parse_in)->missing_header = find_subframework_header;
552 }
553
554 /* Search for HEADER in context dependent way. The return value is
555 the malloced name of a header to try and open, if any, or NULL
556 otherwise. This is called after normal header lookup processing
557 fails to find a header. We search each file in the include stack,
558 using FUNC, starting from the most deeply nested include and
559 finishing with the main input file. We stop searching when FUNC
560 returns nonzero. */
561
562 static const char*
563 find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
564 {
565 const char *fname = header;
566 struct cpp_buffer *b;
567 const char *n;
568
569 for (b = cpp_get_buffer (pfile);
570 b && cpp_get_file (b) && cpp_get_path (cpp_get_file (b));
571 b = cpp_get_prev (b))
572 {
573 n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b)));
574 if (n)
575 {
576 /* Logically, the place where we found the subframework is
577 the place where we found the Framework that contains the
578 subframework. This is useful for tracking wether or not
579 we are in a system header. */
580 *dirp = cpp_get_dir (cpp_get_file (b));
581 return n;
582 }
583 }
584
585 return 0;
586 }
587
588 /* Given an OS X version VERSION_STR, return it as a statically-allocated array
589 of three integers. If VERSION_STR is invalid, return NULL.
590
591 VERSION_STR must consist of one, two, or three tokens, each separated by
592 a single period. Each token must contain only the characters '0' through
593 '9' and is converted to an equivalent non-negative decimal integer. Omitted
594 tokens become zeros. For example:
595
596 "10" becomes {10,0,0}
597 "10.10" becomes {10,10,0}
598 "10.10.1" becomes {10,10,1}
599 "10.000010.1" becomes {10,10,1}
600 "10.010.001" becomes {10,10,1}
601 "000010.10.00001" becomes {10,10,1}
602 ".9.1" is invalid
603 "10..9" is invalid
604 "10.10." is invalid */
605
606 enum version_components { MAJOR, MINOR, TINY };
607
608 static const unsigned long *
609 parse_version (const char *version_str)
610 {
611 size_t version_len;
612 char *end;
613 static unsigned long version_array[3];
614
615 version_len = strlen (version_str);
616 if (version_len < 1)
617 return NULL;
618
619 /* Version string must consist of digits and periods only. */
620 if (strspn (version_str, "0123456789.") != version_len)
621 return NULL;
622
623 if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1]))
624 return NULL;
625
626 version_array[MAJOR] = strtoul (version_str, &end, 10);
627 version_str = end + ((*end == '.') ? 1 : 0);
628
629 /* Version string must not contain adjacent periods. */
630 if (*version_str == '.')
631 return NULL;
632
633 version_array[MINOR] = strtoul (version_str, &end, 10);
634 version_str = end + ((*end == '.') ? 1 : 0);
635
636 version_array[TINY] = strtoul (version_str, &end, 10);
637
638 /* Version string must contain no more than three tokens. */
639 if (*end != '\0')
640 return NULL;
641
642 return version_array;
643 }
644
645 /* Given VERSION -- a three-component OS X version represented as an array of
646 non-negative integers -- return a statically-allocated string suitable for
647 the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION
648 is invalid and cannot be coerced into a valid form, return NULL.
649
650 The legacy format is a four-character string -- two chars for the major
651 number and one each for the minor and tiny numbers. Minor and tiny numbers
652 from 10 through 99 are permitted but are clamped to 9 (for example, {10,9,10}
653 produces "1099"). If VERSION contains numbers greater than 99, it is
654 rejected. */
655
656 static const char *
657 version_as_legacy_macro (const unsigned long *version)
658 {
659 unsigned long major, minor, tiny;
660 static char result[5];
661
662 major = version[MAJOR];
663 minor = version[MINOR];
664 tiny = version[TINY];
665
666 if (major > 99 || minor > 99 || tiny > 99)
667 return NULL;
668
669 minor = ((minor > 9) ? 9 : minor);
670 tiny = ((tiny > 9) ? 9 : tiny);
671
672 if (sprintf (result, "%lu%lu%lu", major, minor, tiny) != 4)
673 return NULL;
674
675 return result;
676 }
677
678 /* Given VERSION -- a three-component OS X version represented as an array of
679 non-negative integers -- return a statically-allocated string suitable for
680 the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION
681 is invalid, return NULL.
682
683 The modern format is a six-character string -- two chars for each component,
684 with zero-padding if necessary (for example, {10,10,1} produces "101001"). If
685 VERSION contains numbers greater than 99, it is rejected. */
686
687 static const char *
688 version_as_modern_macro (const unsigned long *version)
689 {
690 unsigned long major, minor, tiny;
691 static char result[7];
692
693 major = version[MAJOR];
694 minor = version[MINOR];
695 tiny = version[TINY];
696
697 if (major > 99 || minor > 99 || tiny > 99)
698 return NULL;
699
700 if (sprintf (result, "%02lu%02lu%02lu", major, minor, tiny) != 6)
701 return NULL;
702
703 return result;
704 }
705
706 /* Return the value of darwin_macosx_version_min, suitably formatted for the
707 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. Values representing
708 OS X 10.9 and earlier are encoded using the legacy four-character format,
709 while 10.10 and later use a modern six-character format. (For example,
710 "10.9" produces "1090", and "10.10.1" produces "101001".) If
711 darwin_macosx_version_min is invalid and cannot be coerced into a valid
712 form, print a warning and return "1000". */
713
714 static const char *
715 macosx_version_as_macro (void)
716 {
717 const unsigned long *version_array;
718 const char *version_macro;
719
720 version_array = parse_version (darwin_macosx_version_min);
721 if (!version_array)
722 goto fail;
723
724 if (version_array[MAJOR] != 10)
725 goto fail;
726
727 if (version_array[MINOR] < 10)
728 version_macro = version_as_legacy_macro (version_array);
729 else
730 version_macro = version_as_modern_macro (version_array);
731
732 if (!version_macro)
733 goto fail;
734
735 return version_macro;
736
737 fail:
738 error ("unknown value %qs of -mmacosx-version-min",
739 darwin_macosx_version_min);
740 return "1000";
741 }
742
743 /* Define additional CPP flags for Darwin. */
744
745 #define builtin_define(TXT) cpp_define (pfile, TXT)
746
747 void
748 darwin_cpp_builtins (cpp_reader *pfile)
749 {
750 builtin_define ("__MACH__");
751 builtin_define ("__APPLE__");
752
753 /* __APPLE_CC__ is defined as some old Apple include files expect it
754 to be defined and won't work if it isn't. */
755 builtin_define_with_value ("__APPLE_CC__", "1", false);
756
757 if (darwin_constant_cfstrings)
758 builtin_define ("__CONSTANT_CFSTRINGS__");
759
760 builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
761 macosx_version_as_macro(), false);
762
763 /* Since we do not (at 4.6) support ObjC gc for the NeXT runtime, the
764 following will cause a syntax error if one tries to compile gc attributed
765 items. However, without this, NeXT system headers cannot be parsed
766 properly (on systems >= darwin 9). */
767 if (flag_objc_gc)
768 {
769 builtin_define ("__strong=__attribute__((objc_gc(strong)))");
770 builtin_define ("__weak=__attribute__((objc_gc(weak)))");
771 builtin_define ("__OBJC_GC__");
772 }
773 else
774 {
775 builtin_define ("__strong=");
776 builtin_define ("__weak=");
777 }
778
779 if (CPP_OPTION (pfile, objc) && flag_objc_abi == 2)
780 builtin_define ("__OBJC2__");
781 }
782
783 /* Handle C family front-end options. */
784
785 static bool
786 handle_c_option (size_t code,
787 const char *arg,
788 int value ATTRIBUTE_UNUSED)
789 {
790 switch (code)
791 {
792 default:
793 /* Unrecognized options that we said we'd handle turn into
794 errors if not listed here. */
795 return false;
796
797 case OPT_iframework:
798 add_system_framework_path (xstrdup (arg));
799 break;
800
801 case OPT_fapple_kext:
802 ;
803 }
804
805 /* We recognized the option. */
806 return true;
807 }
808
809 /* Allow ObjC* access to CFStrings. */
810 static tree
811 darwin_objc_construct_string (tree str)
812 {
813 if (!darwin_constant_cfstrings)
814 {
815 /* Even though we are not using CFStrings, place our literal
816 into the cfstring_htab hash table, so that the
817 darwin_constant_cfstring_p() function will see it. */
818 darwin_enter_string_into_cfstring_table (str);
819 /* Fall back to NSConstantString. */
820 return NULL_TREE;
821 }
822
823 return darwin_build_constant_cfstring (str);
824 }
825
826 /* The string ref type is created as CFStringRef by <CFBase.h> therefore, we
827 must match for it explicitly, since it's outside the gcc code. */
828
829 static bool
830 darwin_cfstring_ref_p (const_tree strp)
831 {
832 tree tn;
833 if (!strp || TREE_CODE (strp) != POINTER_TYPE)
834 return false;
835
836 tn = TYPE_NAME (strp);
837 if (tn)
838 tn = DECL_NAME (tn);
839 return (tn
840 && IDENTIFIER_POINTER (tn)
841 && !strncmp (IDENTIFIER_POINTER (tn), "CFStringRef", 8));
842 }
843
844 /* At present the behavior of this is undefined and it does nothing. */
845 static void
846 darwin_check_cfstring_format_arg (tree ARG_UNUSED (format_arg),
847 tree ARG_UNUSED (args_list))
848 {
849 }
850
851 /* The extra format types we recognize. */
852 EXPORTED_CONST format_kind_info darwin_additional_format_types[] = {
853 { "CFString", NULL, NULL, NULL, NULL,
854 NULL, NULL,
855 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0,
856 NULL, NULL
857 }
858 };
859
860
861 /* Support routines to dump the class references for NeXT ABI v1, aka
862 32-bits ObjC-2.0, as top-level asms.
863 The following two functions should only be called from
864 objc/objc-next-runtime-abi-01.c. */
865
866 static void
867 darwin_objc_declare_unresolved_class_reference (const char *name)
868 {
869 const char *lazy_reference = ".lazy_reference\t";
870 const char *hard_reference = ".reference\t";
871 const char *reference = MACHOPIC_INDIRECT ? lazy_reference : hard_reference;
872 size_t len = strlen (reference) + strlen(name) + 2;
873 char *buf = (char *) alloca (len);
874
875 gcc_checking_assert (!strncmp (name, ".objc_class_name_", 17));
876
877 snprintf (buf, len, "%s%s", reference, name);
878 symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
879 }
880
881 static void
882 darwin_objc_declare_class_definition (const char *name)
883 {
884 const char *xname = targetm.strip_name_encoding (name);
885 size_t len = strlen (xname) + 7 + 5;
886 char *buf = (char *) alloca (len);
887
888 gcc_checking_assert (!strncmp (name, ".objc_class_name_", 17)
889 || !strncmp (name, "*.objc_category_name_", 21));
890
891 /* Mimic default_globalize_label. */
892 snprintf (buf, len, ".globl\t%s", xname);
893 symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
894
895 snprintf (buf, len, "%s = 0", xname);
896 symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
897 }
898
899 #undef TARGET_HANDLE_C_OPTION
900 #define TARGET_HANDLE_C_OPTION handle_c_option
901
902 #undef TARGET_OBJC_CONSTRUCT_STRING_OBJECT
903 #define TARGET_OBJC_CONSTRUCT_STRING_OBJECT darwin_objc_construct_string
904
905 #undef TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE
906 #define TARGET_OBJC_DECLARE_UNRESOLVED_CLASS_REFERENCE \
907 darwin_objc_declare_unresolved_class_reference
908
909 #undef TARGET_OBJC_DECLARE_CLASS_DEFINITION
910 #define TARGET_OBJC_DECLARE_CLASS_DEFINITION \
911 darwin_objc_declare_class_definition
912
913 #undef TARGET_STRING_OBJECT_REF_TYPE_P
914 #define TARGET_STRING_OBJECT_REF_TYPE_P darwin_cfstring_ref_p
915
916 #undef TARGET_CHECK_STRING_OBJECT_FORMAT_ARG
917 #define TARGET_CHECK_STRING_OBJECT_FORMAT_ARG darwin_check_cfstring_format_arg
918
919 struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;