190075Sobrien/* Darwin support needed only by C/C++ frontends.
2169689Skan   Copyright (C) 2001, 2003, 2004, 2005  Free Software Foundation, Inc.
390075Sobrien   Contributed by Apple Computer Inc.
490075Sobrien
5132718SkanThis file is part of GCC.
690075Sobrien
7132718SkanGCC is free software; you can redistribute it and/or modify
890075Sobrienit under the terms of the GNU General Public License as published by
990075Sobrienthe Free Software Foundation; either version 2, or (at your option)
1090075Sobrienany later version.
1190075Sobrien
12132718SkanGCC is distributed in the hope that it will be useful,
1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1590075SobrienGNU General Public License for more details.
1690075Sobrien
1790075SobrienYou should have received a copy of the GNU General Public License
18132718Skanalong with GCC; see the file COPYING.  If not, write to
19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689SkanBoston, MA 02110-1301, USA.  */
2190075Sobrien
2290075Sobrien#include "config.h"
2390075Sobrien#include "system.h"
24132718Skan#include "coretypes.h"
25132718Skan#include "tm.h"
2690075Sobrien#include "cpplib.h"
2790075Sobrien#include "tree.h"
2890075Sobrien#include "c-pragma.h"
2990075Sobrien#include "c-tree.h"
30169689Skan#include "c-incpath.h"
31169689Skan#include "c-common.h"
3290075Sobrien#include "toplev.h"
33169689Skan#include "flags.h"
3490075Sobrien#include "tm_p.h"
35169689Skan#include "cppdefault.h"
36169689Skan#include "prefix.h"
3790075Sobrien
3890075Sobrien/* Pragmas.  */
3990075Sobrien
40169689Skan#define BAD(gmsgid) do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
41169689Skan#define BAD2(msgid, arg) do { warning (OPT_Wpragmas, msgid, arg); return; } while (0)
4290075Sobrien
43169689Skanstatic bool using_frameworks = false;
44169689Skan
4590075Sobrien/* Maintain a small stack of alignments.  This is similar to pragma
4690075Sobrien   pack's stack, but simpler.  */
4790075Sobrien
48132718Skanstatic void push_field_alignment (int);
49132718Skanstatic void pop_field_alignment (void);
50169689Skanstatic const char *find_subframework_file (const char *, const char *);
51169689Skanstatic void add_system_framework_path (char *);
52169689Skanstatic const char *find_subframework_header (cpp_reader *pfile, const char *header,
53169689Skan					     cpp_dir **dirp);
5490075Sobrien
5590075Sobrientypedef struct align_stack
5690075Sobrien{
5790075Sobrien  int alignment;
5890075Sobrien  struct align_stack * prev;
5990075Sobrien} align_stack;
6090075Sobrien
6190075Sobrienstatic struct align_stack * field_align_stack = NULL;
6290075Sobrien
6390075Sobrienstatic void
64132718Skanpush_field_alignment (int bit_alignment)
6590075Sobrien{
66169689Skan  align_stack *entry = XNEW (align_stack);
6790075Sobrien
6890075Sobrien  entry->alignment = maximum_field_alignment;
6990075Sobrien  entry->prev = field_align_stack;
7090075Sobrien  field_align_stack = entry;
7190075Sobrien
7290075Sobrien  maximum_field_alignment = bit_alignment;
7390075Sobrien}
7490075Sobrien
7590075Sobrienstatic void
76132718Skanpop_field_alignment (void)
7790075Sobrien{
7890075Sobrien  if (field_align_stack)
7990075Sobrien    {
8090075Sobrien      align_stack *entry = field_align_stack;
8190075Sobrien
8290075Sobrien      maximum_field_alignment = entry->alignment;
8390075Sobrien      field_align_stack = entry->prev;
8490075Sobrien      free (entry);
8590075Sobrien    }
8690075Sobrien  else
8790075Sobrien    error ("too many #pragma options align=reset");
8890075Sobrien}
8990075Sobrien
9090075Sobrien/* Handlers for Darwin-specific pragmas.  */
9190075Sobrien
9290075Sobrienvoid
93132718Skandarwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
9490075Sobrien{
9590075Sobrien  /* Do nothing.  */
9690075Sobrien}
9790075Sobrien
9890075Sobrien/* #pragma options align={mac68k|power|reset} */
9990075Sobrien
10090075Sobrienvoid
101132718Skandarwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
10290075Sobrien{
103117395Skan  const char *arg;
10490075Sobrien  tree t, x;
10590075Sobrien
106169689Skan  if (pragma_lex (&t) != CPP_NAME)
10790075Sobrien    BAD ("malformed '#pragma options', ignoring");
10890075Sobrien  arg = IDENTIFIER_POINTER (t);
10990075Sobrien  if (strcmp (arg, "align"))
11090075Sobrien    BAD ("malformed '#pragma options', ignoring");
111169689Skan  if (pragma_lex (&t) != CPP_EQ)
11290075Sobrien    BAD ("malformed '#pragma options', ignoring");
113169689Skan  if (pragma_lex (&t) != CPP_NAME)
11490075Sobrien    BAD ("malformed '#pragma options', ignoring");
11590075Sobrien
116169689Skan  if (pragma_lex (&x) != CPP_EOF)
117169689Skan    warning (OPT_Wpragmas, "junk at end of '#pragma options'");
11890075Sobrien
11990075Sobrien  arg = IDENTIFIER_POINTER (t);
12090075Sobrien  if (!strcmp (arg, "mac68k"))
12190075Sobrien    push_field_alignment (16);
12290075Sobrien  else if (!strcmp (arg, "power"))
12390075Sobrien    push_field_alignment (0);
12490075Sobrien  else if (!strcmp (arg, "reset"))
12590075Sobrien    pop_field_alignment ();
12690075Sobrien  else
127169689Skan    BAD ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
12890075Sobrien}
12990075Sobrien
13090075Sobrien/* #pragma unused ([var {, var}*]) */
13190075Sobrien
13290075Sobrienvoid
133132718Skandarwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
13490075Sobrien{
13590075Sobrien  tree decl, x;
13690075Sobrien  int tok;
13790075Sobrien
138169689Skan  if (pragma_lex (&x) != CPP_OPEN_PAREN)
13990075Sobrien    BAD ("missing '(' after '#pragma unused', ignoring");
14090075Sobrien
14190075Sobrien  while (1)
14290075Sobrien    {
143169689Skan      tok = pragma_lex (&decl);
14490075Sobrien      if (tok == CPP_NAME && decl)
14590075Sobrien	{
146132718Skan	  tree local = lookup_name (decl);
14790075Sobrien	  if (local && (TREE_CODE (local) == PARM_DECL
14890075Sobrien			|| TREE_CODE (local) == VAR_DECL))
14990075Sobrien	    TREE_USED (local) = 1;
150169689Skan	  tok = pragma_lex (&x);
15190075Sobrien	  if (tok != CPP_COMMA)
15290075Sobrien	    break;
15390075Sobrien	}
15490075Sobrien    }
15590075Sobrien
15690075Sobrien  if (tok != CPP_CLOSE_PAREN)
15790075Sobrien    BAD ("missing ')' after '#pragma unused', ignoring");
15890075Sobrien
159169689Skan  if (pragma_lex (&x) != CPP_EOF)
160169689Skan    BAD ("junk at end of '#pragma unused'");
16190075Sobrien}
162169689Skan
163169689Skan/* Parse the ms_struct pragma.  */
164169689Skanvoid
165169689Skandarwin_pragma_ms_struct (cpp_reader *pfile ATTRIBUTE_UNUSED)
166169689Skan{
167169689Skan  const char *arg;
168169689Skan  tree t;
169169689Skan
170169689Skan  if (pragma_lex (&t) != CPP_NAME)
171169689Skan    BAD ("malformed '#pragma ms_struct', ignoring");
172169689Skan  arg = IDENTIFIER_POINTER (t);
173169689Skan
174169689Skan  if (!strcmp (arg, "on"))
175169689Skan    darwin_ms_struct = true;
176169689Skan  else if (!strcmp (arg, "off") || !strcmp (arg, "reset"))
177169689Skan    darwin_ms_struct = false;
178169689Skan  else
179169689Skan    BAD ("malformed '#pragma ms_struct {on|off|reset}', ignoring");
180169689Skan
181169689Skan  if (pragma_lex (&t) != CPP_EOF)
182169689Skan    BAD ("junk at end of '#pragma ms_struct'");
183169689Skan}
184169689Skan
185169689Skanstatic struct {
186169689Skan  size_t len;
187169689Skan  const char *name;
188169689Skan  cpp_dir* dir;
189169689Skan} *frameworks_in_use;
190169689Skanstatic int num_frameworks = 0;
191169689Skanstatic int max_frameworks = 0;
192169689Skan
193169689Skan
194169689Skan/* Remember which frameworks have been seen, so that we can ensure
195169689Skan   that all uses of that framework come from the same framework.  DIR
196169689Skan   is the place where the named framework NAME, which is of length
197169689Skan   LEN, was found.  We copy the directory name from NAME, as it will be
198169689Skan   freed by others.  */
199169689Skan
200169689Skanstatic void
201169689Skanadd_framework (const char *name, size_t len, cpp_dir *dir)
202169689Skan{
203169689Skan  char *dir_name;
204169689Skan  int i;
205169689Skan  for (i = 0; i < num_frameworks; ++i)
206169689Skan    {
207169689Skan      if (len == frameworks_in_use[i].len
208169689Skan	  && strncmp (name, frameworks_in_use[i].name, len) == 0)
209169689Skan	{
210169689Skan	  return;
211169689Skan	}
212169689Skan    }
213169689Skan  if (i >= max_frameworks)
214169689Skan    {
215169689Skan      max_frameworks = i*2;
216169689Skan      max_frameworks += i == 0;
217169689Skan      frameworks_in_use = xrealloc (frameworks_in_use,
218169689Skan				    max_frameworks*sizeof(*frameworks_in_use));
219169689Skan    }
220169689Skan  dir_name = XNEWVEC (char, len + 1);
221169689Skan  memcpy (dir_name, name, len);
222169689Skan  dir_name[len] = '\0';
223169689Skan  frameworks_in_use[num_frameworks].name = dir_name;
224169689Skan  frameworks_in_use[num_frameworks].len = len;
225169689Skan  frameworks_in_use[num_frameworks].dir = dir;
226169689Skan  ++num_frameworks;
227169689Skan}
228169689Skan
229169689Skan/* Recall if we have seen the named framework NAME, before, and where
230169689Skan   we saw it.  NAME is LEN bytes long.  The return value is the place
231169689Skan   where it was seen before.  */
232169689Skan
233169689Skanstatic struct cpp_dir*
234169689Skanfind_framework (const char *name, size_t len)
235169689Skan{
236169689Skan  int i;
237169689Skan  for (i = 0; i < num_frameworks; ++i)
238169689Skan    {
239169689Skan      if (len == frameworks_in_use[i].len
240169689Skan	  && strncmp (name, frameworks_in_use[i].name, len) == 0)
241169689Skan	{
242169689Skan	  return frameworks_in_use[i].dir;
243169689Skan	}
244169689Skan    }
245169689Skan  return 0;
246169689Skan}
247169689Skan
248169689Skan/* There are two directories in a framework that contain header files,
249169689Skan   Headers and PrivateHeaders.  We search Headers first as it is more
250169689Skan   common to upgrade a header from PrivateHeaders to Headers and when
251169689Skan   that is done, the old one might hang around and be out of data,
252169689Skan   causing grief.  */
253169689Skan
254169689Skanstruct framework_header {const char * dirName; int dirNameLen; };
255169689Skanstatic struct framework_header framework_header_dirs[] = {
256169689Skan  { "Headers", 7 },
257169689Skan  { "PrivateHeaders", 14 },
258169689Skan  { NULL, 0 }
259169689Skan};
260169689Skan
261169689Skan/* Returns a pointer to a malloced string that contains the real pathname
262169689Skan   to the file, given the base name and the name.  */
263169689Skan
264169689Skanstatic char *
265169689Skanframework_construct_pathname (const char *fname, cpp_dir *dir)
266169689Skan{
267169689Skan  char *buf;
268169689Skan  size_t fname_len, frname_len;
269169689Skan  cpp_dir *fast_dir;
270169689Skan  char *frname;
271169689Skan  struct stat st;
272169689Skan  int i;
273169689Skan
274169689Skan  /* Framework names must have a / in them.  */
275169689Skan  buf = strchr (fname, '/');
276169689Skan  if (buf)
277169689Skan    fname_len = buf - fname;
278169689Skan  else
279169689Skan    return 0;
280169689Skan
281169689Skan  fast_dir = find_framework (fname, fname_len);
282169689Skan
283169689Skan  /* Framework includes must all come from one framework.  */
284169689Skan  if (fast_dir && dir != fast_dir)
285169689Skan    return 0;
286169689Skan
287169689Skan  frname = XNEWVEC (char, strlen (fname) + dir->len + 2
288169689Skan		    + strlen(".framework/") + strlen("PrivateHeaders"));
289169689Skan  strncpy (&frname[0], dir->name, dir->len);
290169689Skan  frname_len = dir->len;
291169689Skan  if (frname_len && frname[frname_len-1] != '/')
292169689Skan    frname[frname_len++] = '/';
293169689Skan  strncpy (&frname[frname_len], fname, fname_len);
294169689Skan  frname_len += fname_len;
295169689Skan  strncpy (&frname[frname_len], ".framework/", strlen (".framework/"));
296169689Skan  frname_len += strlen (".framework/");
297169689Skan
298169689Skan  if (fast_dir == 0)
299169689Skan    {
300169689Skan      frname[frname_len-1] = 0;
301169689Skan      if (stat (frname, &st) == 0)
302169689Skan	{
303169689Skan	  /* As soon as we find the first instance of the framework,
304169689Skan	     we stop and never use any later instance of that
305169689Skan	     framework.  */
306169689Skan	  add_framework (fname, fname_len, dir);
307169689Skan	}
308169689Skan      else
309169689Skan	{
310169689Skan	  /* If we can't find the parent directory, no point looking
311169689Skan	     further.  */
312169689Skan	  free (frname);
313169689Skan	  return 0;
314169689Skan	}
315169689Skan      frname[frname_len-1] = '/';
316169689Skan    }
317169689Skan
318169689Skan  /* Append framework_header_dirs and header file name */
319169689Skan  for (i = 0; framework_header_dirs[i].dirName; i++)
320169689Skan    {
321169689Skan      strncpy (&frname[frname_len],
322169689Skan	       framework_header_dirs[i].dirName,
323169689Skan	       framework_header_dirs[i].dirNameLen);
324169689Skan      strcpy (&frname[frname_len + framework_header_dirs[i].dirNameLen],
325169689Skan	      &fname[fname_len]);
326169689Skan
327169689Skan      if (stat (frname, &st) == 0)
328169689Skan	return frname;
329169689Skan    }
330169689Skan
331169689Skan  free (frname);
332169689Skan  return 0;
333169689Skan}
334169689Skan
335169689Skan/* Search for FNAME in sub-frameworks.  pname is the context that we
336169689Skan   wish to search in.  Return the path the file was found at,
337169689Skan   otherwise return 0.  */
338169689Skan
339169689Skanstatic const char*
340169689Skanfind_subframework_file (const char *fname, const char *pname)
341169689Skan{
342169689Skan  char *sfrname;
343169689Skan  const char *dot_framework = ".framework/";
344169689Skan  char *bufptr;
345169689Skan  int sfrname_len, i, fname_len;
346169689Skan  struct cpp_dir *fast_dir;
347169689Skan  static struct cpp_dir subframe_dir;
348169689Skan  struct stat st;
349169689Skan
350169689Skan  bufptr = strchr (fname, '/');
351169689Skan
352169689Skan  /* Subframework files must have / in the name.  */
353169689Skan  if (bufptr == 0)
354169689Skan    return 0;
355169689Skan
356169689Skan  fname_len = bufptr - fname;
357169689Skan  fast_dir = find_framework (fname, fname_len);
358169689Skan
359169689Skan  /* Sub framework header filename includes parent framework name and
360169689Skan     header name in the "CarbonCore/OSUtils.h" form. If it does not
361169689Skan     include slash it is not a sub framework include.  */
362169689Skan  bufptr = strstr (pname, dot_framework);
363169689Skan
364169689Skan  /* If the parent header is not of any framework, then this header
365169689Skan     cannot be part of any subframework.  */
366169689Skan  if (!bufptr)
367169689Skan    return 0;
368169689Skan
369169689Skan  /* Now translate. For example,                  +- bufptr
370169689Skan     fname = CarbonCore/OSUtils.h                 |
371169689Skan     pname = /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
372169689Skan     into
373169689Skan     sfrname = /System/Library/Frameworks/Foundation.framework/Frameworks/CarbonCore.framework/Headers/OSUtils.h */
374169689Skan
375169689Skan  sfrname = XNEWVEC (char, strlen (pname) + strlen (fname) + 2 +
376169689Skan			      strlen ("Frameworks/") + strlen (".framework/")
377169689Skan			      + strlen ("PrivateHeaders"));
378169689Skan
379169689Skan  bufptr += strlen (dot_framework);
380169689Skan
381169689Skan  sfrname_len = bufptr - pname;
382169689Skan
383169689Skan  strncpy (&sfrname[0], pname, sfrname_len);
384169689Skan
385169689Skan  strncpy (&sfrname[sfrname_len], "Frameworks/", strlen ("Frameworks/"));
386169689Skan  sfrname_len += strlen("Frameworks/");
387169689Skan
388169689Skan  strncpy (&sfrname[sfrname_len], fname, fname_len);
389169689Skan  sfrname_len += fname_len;
390169689Skan
391169689Skan  strncpy (&sfrname[sfrname_len], ".framework/", strlen (".framework/"));
392169689Skan  sfrname_len += strlen (".framework/");
393169689Skan
394169689Skan  /* Append framework_header_dirs and header file name */
395169689Skan  for (i = 0; framework_header_dirs[i].dirName; i++)
396169689Skan    {
397169689Skan      strncpy (&sfrname[sfrname_len],
398169689Skan	       framework_header_dirs[i].dirName,
399169689Skan	       framework_header_dirs[i].dirNameLen);
400169689Skan      strcpy (&sfrname[sfrname_len + framework_header_dirs[i].dirNameLen],
401169689Skan	      &fname[fname_len]);
402169689Skan
403169689Skan      if (stat (sfrname, &st) == 0)
404169689Skan	{
405169689Skan	  if (fast_dir != &subframe_dir)
406169689Skan	    {
407169689Skan	      if (fast_dir)
408169689Skan		warning (0, "subframework include %s conflicts with framework include",
409169689Skan			 fname);
410169689Skan	      else
411169689Skan		add_framework (fname, fname_len, &subframe_dir);
412169689Skan	    }
413169689Skan
414169689Skan	  return sfrname;
415169689Skan	}
416169689Skan    }
417169689Skan  free (sfrname);
418169689Skan
419169689Skan  return 0;
420169689Skan}
421169689Skan
422169689Skan/* Add PATH to the system includes. PATH must be malloc-ed and
423169689Skan   NUL-terminated.  System framework paths are C++ aware.  */
424169689Skan
425169689Skanstatic void
426169689Skanadd_system_framework_path (char *path)
427169689Skan{
428169689Skan  int cxx_aware = 1;
429169689Skan  cpp_dir *p;
430169689Skan
431169689Skan  p = XNEW (cpp_dir);
432169689Skan  p->next = NULL;
433169689Skan  p->name = path;
434169689Skan  p->sysp = 1 + !cxx_aware;
435169689Skan  p->construct = framework_construct_pathname;
436169689Skan  using_frameworks = 1;
437169689Skan
438169689Skan  add_cpp_dir_path (p, SYSTEM);
439169689Skan}
440169689Skan
441169689Skan/* Add PATH to the bracket includes. PATH must be malloc-ed and
442169689Skan   NUL-terminated.  */
443169689Skan
444169689Skanvoid
445169689Skanadd_framework_path (char *path)
446169689Skan{
447169689Skan  cpp_dir *p;
448169689Skan
449169689Skan  p = XNEW (cpp_dir);
450169689Skan  p->next = NULL;
451169689Skan  p->name = path;
452169689Skan  p->sysp = 0;
453169689Skan  p->construct = framework_construct_pathname;
454169689Skan  using_frameworks = 1;
455169689Skan
456169689Skan  add_cpp_dir_path (p, BRACKET);
457169689Skan}
458169689Skan
459169689Skanstatic const char *framework_defaults [] =
460169689Skan  {
461169689Skan    "/System/Library/Frameworks",
462169689Skan    "/Library/Frameworks",
463169689Skan  };
464169689Skan
465169689Skan/* Register the GNU objective-C runtime include path if STDINC.  */
466169689Skan
467169689Skanvoid
468169689Skandarwin_register_objc_includes (const char *sysroot, const char *iprefix,
469169689Skan			       int stdinc)
470169689Skan{
471169689Skan  const char *fname;
472169689Skan  size_t len;
473169689Skan  /* We do not do anything if we do not want the standard includes. */
474169689Skan  if (!stdinc)
475169689Skan    return;
476169689Skan
477169689Skan  fname = GCC_INCLUDE_DIR "-gnu-runtime";
478169689Skan
479169689Skan  /* Register the GNU OBJC runtime include path if we are compiling  OBJC
480169689Skan    with GNU-runtime.  */
481169689Skan
482169689Skan  if (c_dialect_objc () && !flag_next_runtime)
483169689Skan    {
484169689Skan      char *str;
485169689Skan      /* See if our directory starts with the standard prefix.
486169689Skan	 "Translate" them, i.e. replace /usr/local/lib/gcc... with
487169689Skan	 IPREFIX and search them first.  */
488169689Skan      if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0 && !sysroot
489169689Skan	  && !strncmp (fname, cpp_GCC_INCLUDE_DIR, len))
490169689Skan	{
491169689Skan	  str = concat (iprefix, fname + len, NULL);
492169689Skan          /* FIXME: wrap the headers for C++awareness.  */
493169689Skan	  add_path (str, SYSTEM, /*c++aware=*/false, false);
494169689Skan	}
495169689Skan
496169689Skan      /* Should this directory start with the sysroot?  */
497169689Skan      if (sysroot)
498169689Skan	str = concat (sysroot, fname, NULL);
499169689Skan      else
500169689Skan	str = update_path (fname, "");
501169689Skan
502169689Skan      add_path (str, SYSTEM, /*c++aware=*/false, false);
503169689Skan    }
504169689Skan}
505169689Skan
506169689Skan
507169689Skan/* Register all the system framework paths if STDINC is true and setup
508169689Skan   the missing_header callback for subframework searching if any
509169689Skan   frameworks had been registered.  */
510169689Skan
511169689Skanvoid
512169689Skandarwin_register_frameworks (const char *sysroot,
513169689Skan			    const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
514169689Skan{
515169689Skan  if (stdinc)
516169689Skan    {
517169689Skan      size_t i;
518169689Skan
519169689Skan      /* Setup default search path for frameworks.  */
520169689Skan      for (i=0; i<sizeof (framework_defaults)/sizeof(const char *); ++i)
521169689Skan	{
522169689Skan	  char *str;
523169689Skan	  if (sysroot)
524169689Skan	    str = concat (sysroot, xstrdup (framework_defaults [i]), NULL);
525169689Skan	  else
526169689Skan	    str = xstrdup (framework_defaults[i]);
527169689Skan	  /* System Framework headers are cxx aware.  */
528169689Skan	  add_system_framework_path (str);
529169689Skan	}
530169689Skan    }
531169689Skan
532169689Skan  if (using_frameworks)
533169689Skan    cpp_get_callbacks (parse_in)->missing_header = find_subframework_header;
534169689Skan}
535169689Skan
536169689Skan/* Search for HEADER in context dependent way.  The return value is
537169689Skan   the malloced name of a header to try and open, if any, or NULL
538169689Skan   otherwise.  This is called after normal header lookup processing
539169689Skan   fails to find a header.  We search each file in the include stack,
540169689Skan   using FUNC, starting from the most deeply nested include and
541169689Skan   finishing with the main input file.  We stop searching when FUNC
542169689Skan   returns nonzero.  */
543169689Skan
544169689Skanstatic const char*
545169689Skanfind_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
546169689Skan{
547169689Skan  const char *fname = header;
548169689Skan  struct cpp_buffer *b;
549169689Skan  const char *n;
550169689Skan
551169689Skan  for (b = cpp_get_buffer (pfile);
552169689Skan       b && cpp_get_file (b) && cpp_get_path (cpp_get_file (b));
553169689Skan       b = cpp_get_prev (b))
554169689Skan    {
555169689Skan      n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b)));
556169689Skan      if (n)
557169689Skan	{
558169689Skan	  /* Logically, the place where we found the subframework is
559169689Skan	     the place where we found the Framework that contains the
560169689Skan	     subframework.  This is useful for tracking wether or not
561169689Skan	     we are in a system header.  */
562169689Skan	  *dirp = cpp_get_dir (cpp_get_file (b));
563169689Skan	  return n;
564169689Skan	}
565169689Skan    }
566169689Skan
567169689Skan  return 0;
568169689Skan}
569169689Skan
570169689Skan/* Return the value of darwin_macosx_version_min suitable for the
571169689Skan   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro,
572169689Skan   so '10.4.2' becomes 1042.
573169689Skan   Print a warning if the version number is not known.  */
574169689Skanstatic const char *
575169689Skanversion_as_macro (void)
576169689Skan{
577169689Skan  static char result[] = "1000";
578169689Skan
579169689Skan  if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
580169689Skan    goto fail;
581169689Skan  if (! ISDIGIT (darwin_macosx_version_min[3]))
582169689Skan    goto fail;
583169689Skan  result[2] = darwin_macosx_version_min[3];
584169689Skan  if (darwin_macosx_version_min[4] != '\0')
585169689Skan    {
586169689Skan      if (darwin_macosx_version_min[4] != '.')
587169689Skan	goto fail;
588169689Skan      if (! ISDIGIT (darwin_macosx_version_min[5]))
589169689Skan	goto fail;
590169689Skan      if (darwin_macosx_version_min[6] != '\0')
591169689Skan	goto fail;
592169689Skan      result[3] = darwin_macosx_version_min[5];
593169689Skan    }
594169689Skan  else
595169689Skan    result[3] = '0';
596169689Skan
597169689Skan  return result;
598169689Skan
599169689Skan fail:
600169689Skan  error ("Unknown value %qs of -mmacosx-version-min",
601169689Skan	 darwin_macosx_version_min);
602169689Skan  return "1000";
603169689Skan}
604169689Skan
605169689Skan/* Define additional CPP flags for Darwin.   */
606169689Skan
607169689Skan#define builtin_define(TXT) cpp_define (pfile, TXT)
608169689Skan
609169689Skanvoid
610169689Skandarwin_cpp_builtins (cpp_reader *pfile)
611169689Skan{
612169689Skan  builtin_define ("__MACH__");
613169689Skan  builtin_define ("__APPLE__");
614169689Skan
615169689Skan  /* __APPLE_CC__ is defined as some old Apple include files expect it
616169689Skan     to be defined and won't work if it isn't.  */
617169689Skan  builtin_define_with_value ("__APPLE_CC__", "1", false);
618169689Skan
619169689Skan  if (darwin_macosx_version_min)
620169689Skan    builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
621169689Skan			       version_as_macro(), false);
622169689Skan}
623