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