/* Darwin support needed only by C/C++ frontends.
- Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "c-pragma.h"
#include "c-tree.h"
#include "c-incpath.h"
+#include "c-common.h"
#include "toplev.h"
+#include "flags.h"
#include "tm_p.h"
+#include "cppdefault.h"
+#include "prefix.h"
+#include "target.h"
+#include "target-def.h"
/* Pragmas. */
-#define BAD(msgid) do { warning (msgid); return; } while (0)
+#define BAD(gmsgid) do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
+#define BAD2(msgid, arg) do { warning (OPT_Wpragmas, msgid, arg); return; } while (0)
static bool using_frameworks = false;
-/* Maintain a small stack of alignments. This is similar to pragma
- pack's stack, but simpler. */
-
-static void push_field_alignment (int);
-static void pop_field_alignment (void);
-static const char *find_subframework_file (const char *, const char *);
-static void add_system_framework_path (char *);
static const char *find_subframework_header (cpp_reader *pfile, const char *header,
cpp_dir **dirp);
static struct align_stack * field_align_stack = NULL;
+/* Maintain a small stack of alignments. This is similar to pragma
+ pack's stack, but simpler. */
+
static void
push_field_alignment (int bit_alignment)
{
- align_stack *entry = (align_stack *) xmalloc (sizeof (align_stack));
+ align_stack *entry = XNEW (align_stack);
entry->alignment = maximum_field_alignment;
entry->prev = field_align_stack;
const char *arg;
tree t, x;
- if (c_lex (&t) != CPP_NAME)
+ if (pragma_lex (&t) != CPP_NAME)
BAD ("malformed '#pragma options', ignoring");
arg = IDENTIFIER_POINTER (t);
if (strcmp (arg, "align"))
BAD ("malformed '#pragma options', ignoring");
- if (c_lex (&t) != CPP_EQ)
+ if (pragma_lex (&t) != CPP_EQ)
BAD ("malformed '#pragma options', ignoring");
- if (c_lex (&t) != CPP_NAME)
+ if (pragma_lex (&t) != CPP_NAME)
BAD ("malformed '#pragma options', ignoring");
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of '#pragma options'");
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (OPT_Wpragmas, "junk at end of '#pragma options'");
arg = IDENTIFIER_POINTER (t);
if (!strcmp (arg, "mac68k"))
else if (!strcmp (arg, "reset"))
pop_field_alignment ();
else
- warning ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
+ BAD ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
}
/* #pragma unused ([var {, var}*]) */
tree decl, x;
int tok;
- if (c_lex (&x) != CPP_OPEN_PAREN)
+ if (pragma_lex (&x) != CPP_OPEN_PAREN)
BAD ("missing '(' after '#pragma unused', ignoring");
while (1)
{
- tok = c_lex (&decl);
+ tok = pragma_lex (&decl);
if (tok == CPP_NAME && decl)
{
tree local = lookup_name (decl);
if (local && (TREE_CODE (local) == PARM_DECL
|| TREE_CODE (local) == VAR_DECL))
TREE_USED (local) = 1;
- tok = c_lex (&x);
+ tok = pragma_lex (&x);
if (tok != CPP_COMMA)
break;
}
if (tok != CPP_CLOSE_PAREN)
BAD ("missing ')' after '#pragma unused', ignoring");
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of '#pragma unused'");
+ if (pragma_lex (&x) != CPP_EOF)
+ BAD ("junk at end of '#pragma unused'");
+}
+
+/* Parse the ms_struct pragma. */
+void
+darwin_pragma_ms_struct (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ const char *arg;
+ tree t;
+
+ if (pragma_lex (&t) != CPP_NAME)
+ BAD ("malformed '#pragma ms_struct', ignoring");
+ arg = IDENTIFIER_POINTER (t);
+
+ if (!strcmp (arg, "on"))
+ darwin_ms_struct = true;
+ else if (!strcmp (arg, "off") || !strcmp (arg, "reset"))
+ darwin_ms_struct = false;
+ else
+ BAD ("malformed '#pragma ms_struct {on|off|reset}', ignoring");
+
+ if (pragma_lex (&t) != CPP_EOF)
+ BAD ("junk at end of '#pragma ms_struct'");
}
static struct {
frameworks_in_use = xrealloc (frameworks_in_use,
max_frameworks*sizeof(*frameworks_in_use));
}
- dir_name = xmalloc (len + 1);
+ dir_name = XNEWVEC (char, len + 1);
memcpy (dir_name, name, len);
dir_name[len] = '\0';
frameworks_in_use[num_frameworks].name = dir_name;
if (fast_dir && dir != fast_dir)
return 0;
- frname = xmalloc (strlen (fname) + dir->len + 2
+ frname = XNEWVEC (char, strlen (fname) + dir->len + 2
+ strlen(".framework/") + strlen("PrivateHeaders"));
strncpy (&frname[0], dir->name, dir->len);
frname_len = dir->len;
strncpy (&frname[frname_len], ".framework/", strlen (".framework/"));
frname_len += strlen (".framework/");
+ if (fast_dir == 0)
+ {
+ frname[frname_len-1] = 0;
+ if (stat (frname, &st) == 0)
+ {
+ /* As soon as we find the first instance of the framework,
+ we stop and never use any later instance of that
+ framework. */
+ add_framework (fname, fname_len, dir);
+ }
+ else
+ {
+ /* If we can't find the parent directory, no point looking
+ further. */
+ free (frname);
+ return 0;
+ }
+ frname[frname_len-1] = '/';
+ }
+
/* Append framework_header_dirs and header file name */
for (i = 0; framework_header_dirs[i].dirName; i++)
{
- strncpy (&frname[frname_len],
+ strncpy (&frname[frname_len],
framework_header_dirs[i].dirName,
framework_header_dirs[i].dirNameLen);
strcpy (&frname[frname_len + framework_header_dirs[i].dirNameLen],
&fname[fname_len]);
if (stat (frname, &st) == 0)
- {
- if (fast_dir == 0)
- add_framework (fname, fname_len, dir);
- return frname;
- }
+ return frname;
}
free (frname);
{
char *sfrname;
const char *dot_framework = ".framework/";
- char *bufptr;
- int sfrname_len, i, fname_len;
+ char *bufptr;
+ int sfrname_len, i, fname_len;
struct cpp_dir *fast_dir;
static struct cpp_dir subframe_dir;
struct stat st;
/* Subframework files must have / in the name. */
if (bufptr == 0)
return 0;
-
+
fname_len = bufptr - fname;
fast_dir = find_framework (fname, fname_len);
return 0;
/* Now translate. For example, +- bufptr
- fname = CarbonCore/OSUtils.h |
+ fname = CarbonCore/OSUtils.h |
pname = /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
into
sfrname = /System/Library/Frameworks/Foundation.framework/Frameworks/CarbonCore.framework/Headers/OSUtils.h */
- sfrname = (char *) xmalloc (strlen (pname) + strlen (fname) + 2 +
+ sfrname = XNEWVEC (char, strlen (pname) + strlen (fname) + 2 +
strlen ("Frameworks/") + strlen (".framework/")
+ strlen ("PrivateHeaders"));
-
+
bufptr += strlen (dot_framework);
- sfrname_len = bufptr - pname;
+ sfrname_len = bufptr - pname;
strncpy (&sfrname[0], pname, sfrname_len);
/* Append framework_header_dirs and header file name */
for (i = 0; framework_header_dirs[i].dirName; i++)
{
- strncpy (&sfrname[sfrname_len],
+ strncpy (&sfrname[sfrname_len],
framework_header_dirs[i].dirName,
framework_header_dirs[i].dirNameLen);
strcpy (&sfrname[sfrname_len + framework_header_dirs[i].dirNameLen],
&fname[fname_len]);
-
+
if (stat (sfrname, &st) == 0)
{
if (fast_dir != &subframe_dir)
{
if (fast_dir)
- warning ("subframework include %s conflicts with framework include",
+ warning (0, "subframework include %s conflicts with framework include",
fname);
else
add_framework (fname, fname_len, &subframe_dir);
int cxx_aware = 1;
cpp_dir *p;
- p = xmalloc (sizeof (cpp_dir));
+ p = XNEW (cpp_dir);
p->next = NULL;
p->name = path;
p->sysp = 1 + !cxx_aware;
{
cpp_dir *p;
- p = xmalloc (sizeof (cpp_dir));
+ p = XNEW (cpp_dir);
p->next = NULL;
p->name = path;
p->sysp = 0;
add_cpp_dir_path (p, BRACKET);
}
-static const char *framework_defaults [] =
+static const char *framework_defaults [] =
{
"/System/Library/Frameworks",
"/Library/Frameworks",
};
+/* Register the GNU objective-C runtime include path if STDINC. */
+
+void
+darwin_register_objc_includes (const char *sysroot, const char *iprefix,
+ int stdinc)
+{
+ const char *fname;
+ size_t len;
+ /* We do not do anything if we do not want the standard includes. */
+ if (!stdinc)
+ return;
+
+ fname = GCC_INCLUDE_DIR "-gnu-runtime";
+
+ /* Register the GNU OBJC runtime include path if we are compiling OBJC
+ with GNU-runtime. */
+
+ if (c_dialect_objc () && !flag_next_runtime)
+ {
+ char *str;
+ /* See if our directory starts with the standard prefix.
+ "Translate" them, i.e. replace /usr/local/lib/gcc... with
+ IPREFIX and search them first. */
+ if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0 && !sysroot
+ && !strncmp (fname, cpp_GCC_INCLUDE_DIR, len))
+ {
+ str = concat (iprefix, fname + len, NULL);
+ /* FIXME: wrap the headers for C++awareness. */
+ add_path (str, SYSTEM, /*c++aware=*/false, false);
+ }
+
+ /* Should this directory start with the sysroot? */
+ if (sysroot)
+ str = concat (sysroot, fname, NULL);
+ else
+ str = update_path (fname, "");
+
+ add_path (str, SYSTEM, /*c++aware=*/false, false);
+ }
+}
+
/* Register all the system framework paths if STDINC is true and setup
the missing_header callback for subframework searching if any
frameworks had been registered. */
void
-darwin_register_frameworks (int stdinc)
+darwin_register_frameworks (const char *sysroot,
+ const char *iprefix ATTRIBUTE_UNUSED, int stdinc)
{
if (stdinc)
{
/* Setup default search path for frameworks. */
for (i=0; i<sizeof (framework_defaults)/sizeof(const char *); ++i)
{
+ char *str;
+ if (sysroot)
+ str = concat (sysroot, xstrdup (framework_defaults [i]), NULL);
+ else
+ str = xstrdup (framework_defaults[i]);
/* System Framework headers are cxx aware. */
- add_system_framework_path (xstrdup (framework_defaults[i]));
+ add_system_framework_path (str);
}
}
return 0;
}
-struct target_c_incpath_s target_c_incpath = C_INCPATH_INIT;
+/* Return the value of darwin_macosx_version_min suitable for the
+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro,
+ so '10.4.2' becomes 1040. The lowest digit is always zero.
+ Print a warning if the version number can't be understood. */
+static const char *
+version_as_macro (void)
+{
+ static char result[] = "1000";
+
+ if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
+ goto fail;
+ if (! ISDIGIT (darwin_macosx_version_min[3]))
+ goto fail;
+ result[2] = darwin_macosx_version_min[3];
+ if (darwin_macosx_version_min[4] != '\0'
+ && darwin_macosx_version_min[4] != '.')
+ goto fail;
+
+ return result;
+
+ fail:
+ error ("Unknown value %qs of -mmacosx-version-min",
+ darwin_macosx_version_min);
+ return "1000";
+}
+
+/* Define additional CPP flags for Darwin. */
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+
+void
+darwin_cpp_builtins (cpp_reader *pfile)
+{
+ builtin_define ("__MACH__");
+ builtin_define ("__APPLE__");
+
+ /* __APPLE_CC__ is defined as some old Apple include files expect it
+ to be defined and won't work if it isn't. */
+ builtin_define_with_value ("__APPLE_CC__", "1", false);
+
+ builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
+ version_as_macro(), false);
+}
+
+/* Handle C family front-end options. */
+
+static bool
+handle_c_option (size_t code,
+ const char *arg,
+ int value ATTRIBUTE_UNUSED)
+{
+ switch (code)
+ {
+ default:
+ /* Unrecognized options that we said we'd handle turn into
+ errors if not listed here. */
+ return false;
+
+ case OPT_iframework:
+ add_system_framework_path (xstrdup (arg));
+ break;
+
+ case OPT_fapple_kext:
+ ;
+ }
+
+ /* We recognized the option. */
+ return true;
+}
+
+#undef TARGET_HANDLE_C_OPTION
+#define TARGET_HANDLE_C_OPTION handle_c_option
+
+struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;