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