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