00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "cpplib.h"
00027 #include "tree.h"
00028 #include "c-pragma.h"
00029 #include "c-tree.h"
00030 #include "c-incpath.h"
00031 #include "toplev.h"
00032 #include "tm_p.h"
00033 #include "cppdefault.h"
00034 #include "prefix.h"
00035
00036
00037
00038 #define BAD(gmsgid) do { warning (gmsgid); return; } while (0)
00039
00040 static bool using_frameworks = false;
00041
00042
00043
00044
00045 static void push_field_alignment (int);
00046 static void pop_field_alignment (void);
00047 static const char *find_subframework_file (const char *, const char *);
00048 static void add_system_framework_path (char *);
00049 static const char *find_subframework_header (cpp_reader *pfile, const char *header,
00050 cpp_dir **dirp);
00051
00052 typedef struct align_stack
00053 {
00054 int alignment;
00055 struct align_stack * prev;
00056 } align_stack;
00057
00058 static struct align_stack * field_align_stack = NULL;
00059
00060 static void
00061 push_field_alignment (int bit_alignment)
00062 {
00063 align_stack *entry = (align_stack *) xmalloc (sizeof (align_stack));
00064
00065 entry->alignment = maximum_field_alignment;
00066 entry->prev = field_align_stack;
00067 field_align_stack = entry;
00068
00069 maximum_field_alignment = bit_alignment;
00070 }
00071
00072 static void
00073 pop_field_alignment (void)
00074 {
00075 if (field_align_stack)
00076 {
00077 align_stack *entry = field_align_stack;
00078
00079 maximum_field_alignment = entry->alignment;
00080 field_align_stack = entry->prev;
00081 free (entry);
00082 }
00083 else
00084 error ("too many #pragma options align=reset");
00085 }
00086
00087
00088
00089 void
00090 darwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
00091 {
00092
00093 }
00094
00095
00096
00097 void
00098 darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
00099 {
00100 const char *arg;
00101 tree t, x;
00102
00103 if (c_lex (&t) != CPP_NAME)
00104 BAD ("malformed '#pragma options', ignoring");
00105 arg = IDENTIFIER_POINTER (t);
00106 if (strcmp (arg, "align"))
00107 BAD ("malformed '#pragma options', ignoring");
00108 if (c_lex (&t) != CPP_EQ)
00109 BAD ("malformed '#pragma options', ignoring");
00110 if (c_lex (&t) != CPP_NAME)
00111 BAD ("malformed '#pragma options', ignoring");
00112
00113 if (c_lex (&x) != CPP_EOF)
00114 warning ("junk at end of '#pragma options'");
00115
00116 arg = IDENTIFIER_POINTER (t);
00117 if (!strcmp (arg, "mac68k"))
00118 push_field_alignment (16);
00119 else if (!strcmp (arg, "power"))
00120 push_field_alignment (0);
00121 else if (!strcmp (arg, "reset"))
00122 pop_field_alignment ();
00123 else
00124 warning ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
00125 }
00126
00127
00128
00129 void
00130 darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
00131 {
00132 tree decl, x;
00133 int tok;
00134
00135 if (c_lex (&x) != CPP_OPEN_PAREN)
00136 BAD ("missing '(' after '#pragma unused', ignoring");
00137
00138 while (1)
00139 {
00140 tok = c_lex (&decl);
00141 if (tok == CPP_NAME && decl)
00142 {
00143 tree local = lookup_name (decl);
00144 if (local && (TREE_CODE (local) == PARM_DECL
00145 || TREE_CODE (local) == VAR_DECL))
00146 TREE_USED (local) = 1;
00147 tok = c_lex (&x);
00148 if (tok != CPP_COMMA)
00149 break;
00150 }
00151 }
00152
00153 if (tok != CPP_CLOSE_PAREN)
00154 BAD ("missing ')' after '#pragma unused', ignoring");
00155
00156 if (c_lex (&x) != CPP_EOF)
00157 warning ("junk at end of '#pragma unused'");
00158 }
00159
00160 static struct {
00161 size_t len;
00162 const char *name;
00163 cpp_dir* dir;
00164 } *frameworks_in_use;
00165 static int num_frameworks = 0;
00166 static int max_frameworks = 0;
00167
00168
00169
00170
00171
00172
00173
00174
00175 static void
00176 add_framework (const char *name, size_t len, cpp_dir *dir)
00177 {
00178 char *dir_name;
00179 int i;
00180 for (i = 0; i < num_frameworks; ++i)
00181 {
00182 if (len == frameworks_in_use[i].len
00183 && strncmp (name, frameworks_in_use[i].name, len) == 0)
00184 {
00185 return;
00186 }
00187 }
00188 if (i >= max_frameworks)
00189 {
00190 max_frameworks = i*2;
00191 max_frameworks += i == 0;
00192 frameworks_in_use = xrealloc (frameworks_in_use,
00193 max_frameworks*sizeof(*frameworks_in_use));
00194 }
00195 dir_name = xmalloc (len + 1);
00196 memcpy (dir_name, name, len);
00197 dir_name[len] = '\0';
00198 frameworks_in_use[num_frameworks].name = dir_name;
00199 frameworks_in_use[num_frameworks].len = len;
00200 frameworks_in_use[num_frameworks].dir = dir;
00201 ++num_frameworks;
00202 }
00203
00204
00205
00206
00207
00208 static struct cpp_dir*
00209 find_framework (const char *name, size_t len)
00210 {
00211 int i;
00212 for (i = 0; i < num_frameworks; ++i)
00213 {
00214 if (len == frameworks_in_use[i].len
00215 && strncmp (name, frameworks_in_use[i].name, len) == 0)
00216 {
00217 return frameworks_in_use[i].dir;
00218 }
00219 }
00220 return 0;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 struct framework_header {const char * dirName; int dirNameLen; };
00230 static struct framework_header framework_header_dirs[] = {
00231 { "Headers", 7 },
00232 { "PrivateHeaders", 14 },
00233 { NULL, 0 }
00234 };
00235
00236
00237
00238
00239 static char *
00240 framework_construct_pathname (const char *fname, cpp_dir *dir)
00241 {
00242 char *buf;
00243 size_t fname_len, frname_len;
00244 cpp_dir *fast_dir;
00245 char *frname;
00246 struct stat st;
00247 int i;
00248
00249
00250 buf = strchr (fname, '/');
00251 if (buf)
00252 fname_len = buf - fname;
00253 else
00254 return 0;
00255
00256 fast_dir = find_framework (fname, fname_len);
00257
00258
00259 if (fast_dir && dir != fast_dir)
00260 return 0;
00261
00262 frname = xmalloc (strlen (fname) + dir->len + 2
00263 + strlen(".framework/") + strlen("PrivateHeaders"));
00264 strncpy (&frname[0], dir->name, dir->len);
00265 frname_len = dir->len;
00266 if (frname_len && frname[frname_len-1] != '/')
00267 frname[frname_len++] = '/';
00268 strncpy (&frname[frname_len], fname, fname_len);
00269 frname_len += fname_len;
00270 strncpy (&frname[frname_len], ".framework/", strlen (".framework/"));
00271 frname_len += strlen (".framework/");
00272
00273
00274 for (i = 0; framework_header_dirs[i].dirName; i++)
00275 {
00276 strncpy (&frname[frname_len],
00277 framework_header_dirs[i].dirName,
00278 framework_header_dirs[i].dirNameLen);
00279 strcpy (&frname[frname_len + framework_header_dirs[i].dirNameLen],
00280 &fname[fname_len]);
00281
00282 if (stat (frname, &st) == 0)
00283 {
00284 if (fast_dir == 0)
00285 add_framework (fname, fname_len, dir);
00286 return frname;
00287 }
00288 }
00289
00290 free (frname);
00291 return 0;
00292 }
00293
00294
00295
00296
00297
00298 static const char*
00299 find_subframework_file (const char *fname, const char *pname)
00300 {
00301 char *sfrname;
00302 const char *dot_framework = ".framework/";
00303 char *bufptr;
00304 int sfrname_len, i, fname_len;
00305 struct cpp_dir *fast_dir;
00306 static struct cpp_dir subframe_dir;
00307 struct stat st;
00308
00309 bufptr = strchr (fname, '/');
00310
00311
00312 if (bufptr == 0)
00313 return 0;
00314
00315 fname_len = bufptr - fname;
00316 fast_dir = find_framework (fname, fname_len);
00317
00318
00319
00320
00321 bufptr = strstr (pname, dot_framework);
00322
00323
00324
00325 if (!bufptr)
00326 return 0;
00327
00328
00329
00330
00331
00332
00333
00334 sfrname = (char *) xmalloc (strlen (pname) + strlen (fname) + 2 +
00335 strlen ("Frameworks/") + strlen (".framework/")
00336 + strlen ("PrivateHeaders"));
00337
00338 bufptr += strlen (dot_framework);
00339
00340 sfrname_len = bufptr - pname;
00341
00342 strncpy (&sfrname[0], pname, sfrname_len);
00343
00344 strncpy (&sfrname[sfrname_len], "Frameworks/", strlen ("Frameworks/"));
00345 sfrname_len += strlen("Frameworks/");
00346
00347 strncpy (&sfrname[sfrname_len], fname, fname_len);
00348 sfrname_len += fname_len;
00349
00350 strncpy (&sfrname[sfrname_len], ".framework/", strlen (".framework/"));
00351 sfrname_len += strlen (".framework/");
00352
00353
00354 for (i = 0; framework_header_dirs[i].dirName; i++)
00355 {
00356 strncpy (&sfrname[sfrname_len],
00357 framework_header_dirs[i].dirName,
00358 framework_header_dirs[i].dirNameLen);
00359 strcpy (&sfrname[sfrname_len + framework_header_dirs[i].dirNameLen],
00360 &fname[fname_len]);
00361
00362 if (stat (sfrname, &st) == 0)
00363 {
00364 if (fast_dir != &subframe_dir)
00365 {
00366 if (fast_dir)
00367 warning ("subframework include %s conflicts with framework include",
00368 fname);
00369 else
00370 add_framework (fname, fname_len, &subframe_dir);
00371 }
00372
00373 return sfrname;
00374 }
00375 }
00376 free (sfrname);
00377
00378 return 0;
00379 }
00380
00381
00382
00383
00384 static void
00385 add_system_framework_path (char *path)
00386 {
00387 int cxx_aware = 1;
00388 cpp_dir *p;
00389
00390 p = xmalloc (sizeof (cpp_dir));
00391 p->next = NULL;
00392 p->name = path;
00393 p->sysp = 1 + !cxx_aware;
00394 p->construct = framework_construct_pathname;
00395 using_frameworks = 1;
00396
00397 add_cpp_dir_path (p, SYSTEM);
00398 }
00399
00400
00401
00402
00403 void
00404 add_framework_path (char *path)
00405 {
00406 cpp_dir *p;
00407
00408 p = xmalloc (sizeof (cpp_dir));
00409 p->next = NULL;
00410 p->name = path;
00411 p->sysp = 0;
00412 p->construct = framework_construct_pathname;
00413 using_frameworks = 1;
00414
00415 add_cpp_dir_path (p, BRACKET);
00416 }
00417
00418 static const char *framework_defaults [] =
00419 {
00420 "/System/Library/Frameworks",
00421 "/Library/Frameworks",
00422 };
00423
00424
00425
00426 void
00427 darwin_register_objc_includes (const char *sysroot, const char *iprefix,
00428 int stdinc)
00429 {
00430 const char *fname;
00431 size_t len;
00432
00433 if (!stdinc)
00434 return;
00435
00436 fname = GCC_INCLUDE_DIR "-gnu-runtime";
00437
00438
00439
00440
00441 if (c_dialect_objc () && !flag_next_runtime)
00442 {
00443 char *str;
00444
00445
00446
00447 if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0 && !sysroot
00448 && !strncmp (fname, cpp_GCC_INCLUDE_DIR, len))
00449 {
00450 str = concat (iprefix, fname + len, NULL);
00451
00452 add_path (str, SYSTEM, false, false);
00453 }
00454
00455
00456 if (sysroot)
00457 str = concat (sysroot, fname, NULL);
00458 else
00459 str = update_path (fname, "");
00460
00461 add_path (str, SYSTEM, false, false);
00462 }
00463 }
00464
00465
00466
00467
00468
00469
00470 void
00471 darwin_register_frameworks (const char *sysroot,
00472 const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
00473 {
00474 if (stdinc)
00475 {
00476 size_t i;
00477
00478
00479 for (i=0; i<sizeof (framework_defaults)/sizeof(const char *); ++i)
00480 {
00481 char *str;
00482 if (sysroot)
00483 str = concat (sysroot, xstrdup (framework_defaults [i]), NULL);
00484 else
00485 str = xstrdup (framework_defaults[i]);
00486
00487 add_system_framework_path (str);
00488 }
00489 }
00490
00491 if (using_frameworks)
00492 cpp_get_callbacks (parse_in)->missing_header = find_subframework_header;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 static const char*
00504 find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
00505 {
00506 const char *fname = header;
00507 struct cpp_buffer *b;
00508 const char *n;
00509
00510 for (b = cpp_get_buffer (pfile);
00511 b && cpp_get_file (b) && cpp_get_path (cpp_get_file (b));
00512 b = cpp_get_prev (b))
00513 {
00514 n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b)));
00515 if (n)
00516 {
00517
00518
00519
00520
00521 *dirp = cpp_get_dir (cpp_get_file (b));
00522 return n;
00523 }
00524 }
00525
00526 return 0;
00527 }