Merge from mainline
[official-gcc.git] / gcc / config / darwin-c.c
blob30de35d47a66fef8943665a31c9757c7ba0b7a0a
1 /* Darwin support needed only by C/C++ frontends.
2 Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Apple Computer Inc.
5 This file is part of GCC.
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 2, or (at your option)
10 any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "cpplib.h"
27 #include "tree.h"
28 #include "c-pragma.h"
29 #include "c-tree.h"
30 #include "c-incpath.h"
31 #include "c-common.h"
32 #include "toplev.h"
33 #include "flags.h"
34 #include "tm_p.h"
35 #include "cppdefault.h"
36 #include "prefix.h"
38 /* Pragmas. */
40 #define BAD(gmsgid) do { warning (0, gmsgid); return; } while (0)
42 static bool using_frameworks = false;
44 /* Maintain a small stack of alignments. This is similar to pragma
45 pack's stack, but simpler. */
47 static void push_field_alignment (int);
48 static void pop_field_alignment (void);
49 static const char *find_subframework_file (const char *, const char *);
50 static void add_system_framework_path (char *);
51 static const char *find_subframework_header (cpp_reader *pfile, const char *header,
52 cpp_dir **dirp);
54 typedef struct align_stack
56 int alignment;
57 struct align_stack * prev;
58 } align_stack;
60 static struct align_stack * field_align_stack = NULL;
62 static void
63 push_field_alignment (int bit_alignment)
65 align_stack *entry = XNEW (align_stack);
67 entry->alignment = maximum_field_alignment;
68 entry->prev = field_align_stack;
69 field_align_stack = entry;
71 maximum_field_alignment = bit_alignment;
74 static void
75 pop_field_alignment (void)
77 if (field_align_stack)
79 align_stack *entry = field_align_stack;
81 maximum_field_alignment = entry->alignment;
82 field_align_stack = entry->prev;
83 free (entry);
85 else
86 error ("too many #pragma options align=reset");
89 /* Handlers for Darwin-specific pragmas. */
91 void
92 darwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
94 /* Do nothing. */
97 /* #pragma options align={mac68k|power|reset} */
99 void
100 darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
102 const char *arg;
103 tree t, x;
105 if (pragma_lex (&t) != CPP_NAME)
106 BAD ("malformed '#pragma options', ignoring");
107 arg = IDENTIFIER_POINTER (t);
108 if (strcmp (arg, "align"))
109 BAD ("malformed '#pragma options', ignoring");
110 if (pragma_lex (&t) != CPP_EQ)
111 BAD ("malformed '#pragma options', ignoring");
112 if (pragma_lex (&t) != CPP_NAME)
113 BAD ("malformed '#pragma options', ignoring");
115 if (pragma_lex (&x) != CPP_EOF)
116 warning (0, "junk at end of '#pragma options'");
118 arg = IDENTIFIER_POINTER (t);
119 if (!strcmp (arg, "mac68k"))
120 push_field_alignment (16);
121 else if (!strcmp (arg, "power"))
122 push_field_alignment (0);
123 else if (!strcmp (arg, "reset"))
124 pop_field_alignment ();
125 else
126 warning (0, "malformed '#pragma options align={mac68k|power|reset}', ignoring");
129 /* #pragma unused ([var {, var}*]) */
131 void
132 darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
134 tree decl, x;
135 int tok;
137 if (pragma_lex (&x) != CPP_OPEN_PAREN)
138 BAD ("missing '(' after '#pragma unused', ignoring");
140 while (1)
142 tok = pragma_lex (&decl);
143 if (tok == CPP_NAME && decl)
145 tree local = lookup_name (decl);
146 if (local && (TREE_CODE (local) == PARM_DECL
147 || TREE_CODE (local) == VAR_DECL))
148 TREE_USED (local) = 1;
149 tok = pragma_lex (&x);
150 if (tok != CPP_COMMA)
151 break;
155 if (tok != CPP_CLOSE_PAREN)
156 BAD ("missing ')' after '#pragma unused', ignoring");
158 if (pragma_lex (&x) != CPP_EOF)
159 warning (0, "junk at end of '#pragma unused'");
162 static struct {
163 size_t len;
164 const char *name;
165 cpp_dir* dir;
166 } *frameworks_in_use;
167 static int num_frameworks = 0;
168 static int max_frameworks = 0;
171 /* Remember which frameworks have been seen, so that we can ensure
172 that all uses of that framework come from the same framework. DIR
173 is the place where the named framework NAME, which is of length
174 LEN, was found. We copy the directory name from NAME, as it will be
175 freed by others. */
177 static void
178 add_framework (const char *name, size_t len, cpp_dir *dir)
180 char *dir_name;
181 int i;
182 for (i = 0; i < num_frameworks; ++i)
184 if (len == frameworks_in_use[i].len
185 && strncmp (name, frameworks_in_use[i].name, len) == 0)
187 return;
190 if (i >= max_frameworks)
192 max_frameworks = i*2;
193 max_frameworks += i == 0;
194 frameworks_in_use = xrealloc (frameworks_in_use,
195 max_frameworks*sizeof(*frameworks_in_use));
197 dir_name = XNEWVEC (char, len + 1);
198 memcpy (dir_name, name, len);
199 dir_name[len] = '\0';
200 frameworks_in_use[num_frameworks].name = dir_name;
201 frameworks_in_use[num_frameworks].len = len;
202 frameworks_in_use[num_frameworks].dir = dir;
203 ++num_frameworks;
206 /* Recall if we have seen the named framework NAME, before, and where
207 we saw it. NAME is LEN bytes long. The return value is the place
208 where it was seen before. */
210 static struct cpp_dir*
211 find_framework (const char *name, size_t len)
213 int i;
214 for (i = 0; i < num_frameworks; ++i)
216 if (len == frameworks_in_use[i].len
217 && strncmp (name, frameworks_in_use[i].name, len) == 0)
219 return frameworks_in_use[i].dir;
222 return 0;
225 /* There are two directories in a framework that contain header files,
226 Headers and PrivateHeaders. We search Headers first as it is more
227 common to upgrade a header from PrivateHeaders to Headers and when
228 that is done, the old one might hang around and be out of data,
229 causing grief. */
231 struct framework_header {const char * dirName; int dirNameLen; };
232 static struct framework_header framework_header_dirs[] = {
233 { "Headers", 7 },
234 { "PrivateHeaders", 14 },
235 { NULL, 0 }
238 /* Returns a pointer to a malloced string that contains the real pathname
239 to the file, given the base name and the name. */
241 static char *
242 framework_construct_pathname (const char *fname, cpp_dir *dir)
244 char *buf;
245 size_t fname_len, frname_len;
246 cpp_dir *fast_dir;
247 char *frname;
248 struct stat st;
249 int i;
251 /* Framework names must have a / in them. */
252 buf = strchr (fname, '/');
253 if (buf)
254 fname_len = buf - fname;
255 else
256 return 0;
258 fast_dir = find_framework (fname, fname_len);
260 /* Framework includes must all come from one framework. */
261 if (fast_dir && dir != fast_dir)
262 return 0;
264 frname = XNEWVEC (char, strlen (fname) + dir->len + 2
265 + strlen(".framework/") + strlen("PrivateHeaders"));
266 strncpy (&frname[0], dir->name, dir->len);
267 frname_len = dir->len;
268 if (frname_len && frname[frname_len-1] != '/')
269 frname[frname_len++] = '/';
270 strncpy (&frname[frname_len], fname, fname_len);
271 frname_len += fname_len;
272 strncpy (&frname[frname_len], ".framework/", strlen (".framework/"));
273 frname_len += strlen (".framework/");
275 if (fast_dir == 0)
277 frname[frname_len-1] = 0;
278 if (stat (frname, &st) == 0)
280 /* As soon as we find the first instance of the framework,
281 we stop and never use any later instance of that
282 framework. */
283 add_framework (fname, fname_len, dir);
285 else
287 /* If we can't find the parent directory, no point looking
288 further. */
289 free (frname);
290 return 0;
292 frname[frname_len-1] = '/';
295 /* Append framework_header_dirs and header file name */
296 for (i = 0; framework_header_dirs[i].dirName; i++)
298 strncpy (&frname[frname_len],
299 framework_header_dirs[i].dirName,
300 framework_header_dirs[i].dirNameLen);
301 strcpy (&frname[frname_len + framework_header_dirs[i].dirNameLen],
302 &fname[fname_len]);
304 if (stat (frname, &st) == 0)
305 return frname;
308 free (frname);
309 return 0;
312 /* Search for FNAME in sub-frameworks. pname is the context that we
313 wish to search in. Return the path the file was found at,
314 otherwise return 0. */
316 static const char*
317 find_subframework_file (const char *fname, const char *pname)
319 char *sfrname;
320 const char *dot_framework = ".framework/";
321 char *bufptr;
322 int sfrname_len, i, fname_len;
323 struct cpp_dir *fast_dir;
324 static struct cpp_dir subframe_dir;
325 struct stat st;
327 bufptr = strchr (fname, '/');
329 /* Subframework files must have / in the name. */
330 if (bufptr == 0)
331 return 0;
333 fname_len = bufptr - fname;
334 fast_dir = find_framework (fname, fname_len);
336 /* Sub framework header filename includes parent framework name and
337 header name in the "CarbonCore/OSUtils.h" form. If it does not
338 include slash it is not a sub framework include. */
339 bufptr = strstr (pname, dot_framework);
341 /* If the parent header is not of any framework, then this header
342 cannot be part of any subframework. */
343 if (!bufptr)
344 return 0;
346 /* Now translate. For example, +- bufptr
347 fname = CarbonCore/OSUtils.h |
348 pname = /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
349 into
350 sfrname = /System/Library/Frameworks/Foundation.framework/Frameworks/CarbonCore.framework/Headers/OSUtils.h */
352 sfrname = XNEWVEC (char, strlen (pname) + strlen (fname) + 2 +
353 strlen ("Frameworks/") + strlen (".framework/")
354 + strlen ("PrivateHeaders"));
356 bufptr += strlen (dot_framework);
358 sfrname_len = bufptr - pname;
360 strncpy (&sfrname[0], pname, sfrname_len);
362 strncpy (&sfrname[sfrname_len], "Frameworks/", strlen ("Frameworks/"));
363 sfrname_len += strlen("Frameworks/");
365 strncpy (&sfrname[sfrname_len], fname, fname_len);
366 sfrname_len += fname_len;
368 strncpy (&sfrname[sfrname_len], ".framework/", strlen (".framework/"));
369 sfrname_len += strlen (".framework/");
371 /* Append framework_header_dirs and header file name */
372 for (i = 0; framework_header_dirs[i].dirName; i++)
374 strncpy (&sfrname[sfrname_len],
375 framework_header_dirs[i].dirName,
376 framework_header_dirs[i].dirNameLen);
377 strcpy (&sfrname[sfrname_len + framework_header_dirs[i].dirNameLen],
378 &fname[fname_len]);
380 if (stat (sfrname, &st) == 0)
382 if (fast_dir != &subframe_dir)
384 if (fast_dir)
385 warning (0, "subframework include %s conflicts with framework include",
386 fname);
387 else
388 add_framework (fname, fname_len, &subframe_dir);
391 return sfrname;
394 free (sfrname);
396 return 0;
399 /* Add PATH to the system includes. PATH must be malloc-ed and
400 NUL-terminated. System framework paths are C++ aware. */
402 static void
403 add_system_framework_path (char *path)
405 int cxx_aware = 1;
406 cpp_dir *p;
408 p = XNEW (cpp_dir);
409 p->next = NULL;
410 p->name = path;
411 p->sysp = 1 + !cxx_aware;
412 p->construct = framework_construct_pathname;
413 using_frameworks = 1;
415 add_cpp_dir_path (p, SYSTEM);
418 /* Add PATH to the bracket includes. PATH must be malloc-ed and
419 NUL-terminated. */
421 void
422 add_framework_path (char *path)
424 cpp_dir *p;
426 p = XNEW (cpp_dir);
427 p->next = NULL;
428 p->name = path;
429 p->sysp = 0;
430 p->construct = framework_construct_pathname;
431 using_frameworks = 1;
433 add_cpp_dir_path (p, BRACKET);
436 static const char *framework_defaults [] =
438 "/System/Library/Frameworks",
439 "/Library/Frameworks",
442 /* Register the GNU objective-C runtime include path if STDINC. */
444 void
445 darwin_register_objc_includes (const char *sysroot, const char *iprefix,
446 int stdinc)
448 const char *fname;
449 size_t len;
450 /* We do not do anything if we do not want the standard includes. */
451 if (!stdinc)
452 return;
454 fname = GCC_INCLUDE_DIR "-gnu-runtime";
456 /* Register the GNU OBJC runtime include path if we are compiling OBJC
457 with GNU-runtime. */
459 if (c_dialect_objc () && !flag_next_runtime)
461 char *str;
462 /* See if our directory starts with the standard prefix.
463 "Translate" them, i.e. replace /usr/local/lib/gcc... with
464 IPREFIX and search them first. */
465 if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0 && !sysroot
466 && !strncmp (fname, cpp_GCC_INCLUDE_DIR, len))
468 str = concat (iprefix, fname + len, NULL);
469 /* FIXME: wrap the headers for C++awareness. */
470 add_path (str, SYSTEM, /*c++aware=*/false, false);
473 /* Should this directory start with the sysroot? */
474 if (sysroot)
475 str = concat (sysroot, fname, NULL);
476 else
477 str = update_path (fname, "");
479 add_path (str, SYSTEM, /*c++aware=*/false, false);
484 /* Register all the system framework paths if STDINC is true and setup
485 the missing_header callback for subframework searching if any
486 frameworks had been registered. */
488 void
489 darwin_register_frameworks (const char *sysroot,
490 const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
492 if (stdinc)
494 size_t i;
496 /* Setup default search path for frameworks. */
497 for (i=0; i<sizeof (framework_defaults)/sizeof(const char *); ++i)
499 char *str;
500 if (sysroot)
501 str = concat (sysroot, xstrdup (framework_defaults [i]), NULL);
502 else
503 str = xstrdup (framework_defaults[i]);
504 /* System Framework headers are cxx aware. */
505 add_system_framework_path (str);
509 if (using_frameworks)
510 cpp_get_callbacks (parse_in)->missing_header = find_subframework_header;
513 /* Search for HEADER in context dependent way. The return value is
514 the malloced name of a header to try and open, if any, or NULL
515 otherwise. This is called after normal header lookup processing
516 fails to find a header. We search each file in the include stack,
517 using FUNC, starting from the most deeply nested include and
518 finishing with the main input file. We stop searching when FUNC
519 returns nonzero. */
521 static const char*
522 find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
524 const char *fname = header;
525 struct cpp_buffer *b;
526 const char *n;
528 for (b = cpp_get_buffer (pfile);
529 b && cpp_get_file (b) && cpp_get_path (cpp_get_file (b));
530 b = cpp_get_prev (b))
532 n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b)));
533 if (n)
535 /* Logically, the place where we found the subframework is
536 the place where we found the Framework that contains the
537 subframework. This is useful for tracking wether or not
538 we are in a system header. */
539 *dirp = cpp_get_dir (cpp_get_file (b));
540 return n;
544 return 0;
547 /* Return the value of darwin_macosx_version_min suitable for the
548 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro,
549 so '10.4.2' becomes 1042.
550 Print a warning if the version number is not known. */
551 static const char *
552 version_as_macro (void)
554 static char result[] = "1000";
556 if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
557 goto fail;
558 if (! ISDIGIT (darwin_macosx_version_min[3]))
559 goto fail;
560 result[2] = darwin_macosx_version_min[3];
561 if (darwin_macosx_version_min[4] != '\0')
563 if (darwin_macosx_version_min[4] != '.')
564 goto fail;
565 if (! ISDIGIT (darwin_macosx_version_min[5]))
566 goto fail;
567 if (darwin_macosx_version_min[6] != '\0')
568 goto fail;
569 result[3] = darwin_macosx_version_min[5];
571 else
572 result[3] = '0';
574 return result;
576 fail:
577 error ("Unknown value %qs of -mmacosx-version-min",
578 darwin_macosx_version_min);
579 return "1000";
582 /* Define additional CPP flags for Darwin. */
584 #define builtin_define(TXT) cpp_define (pfile, TXT)
586 void
587 darwin_cpp_builtins (cpp_reader *pfile)
589 builtin_define ("__MACH__");
590 builtin_define ("__APPLE__");
592 /* __APPLE_CC__ is defined as some old Apple include files expect it
593 to be defined and won't work if it isn't. */
594 builtin_define_with_value ("__APPLE_CC__", "1", false);
596 if (darwin_macosx_version_min)
597 builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
598 version_as_macro(), false);