OSDN Git Service

* config/darwin-c.c (BAD): Conditionalize on OPT_Wpragmas.
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin-c.c
index f15aafb..cecf2b0 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 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"
@@ -28,12 +28,17 @@ Boston, MA 02111-1307, USA.  */
 #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"
 
 /* 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;
 
@@ -58,7 +63,7 @@ static struct align_stack * field_align_stack = NULL;
 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;
@@ -98,18 +103,18 @@ darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
   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 (0, "junk at end of '#pragma options'");
 
   arg = IDENTIFIER_POINTER (t);
   if (!strcmp (arg, "mac68k"))
@@ -119,7 +124,7 @@ darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
   else if (!strcmp (arg, "reset"))
     pop_field_alignment ();
   else
-    warning ("malformed '#pragma options align={mac68k|power|reset}', ignoring");
+    warning (0, "malformed '#pragma options align={mac68k|power|reset}', ignoring");
 }
 
 /* #pragma unused ([var {, var}*]) */
@@ -130,19 +135,19 @@ darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
   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;
        }
@@ -151,8 +156,30 @@ darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
   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)
+    warning (0, "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
+    warning (OPT_Wpragmas, "malformed '#pragma ms_struct {on|off|reset}', ignoring");
+
+  if (pragma_lex (&t) != CPP_EOF)
+    warning (OPT_Wpragmas, "junk at end of '#pragma ms_struct'");
 }
 
 static struct {
@@ -190,7 +217,7 @@ add_framework (const char *name, size_t len, cpp_dir *dir)
       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;
@@ -257,7 +284,7 @@ framework_construct_pathname (const char *fname, cpp_dir *dir)
   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;
@@ -268,21 +295,37 @@ framework_construct_pathname (const char *fname, cpp_dir *dir)
   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);
@@ -298,8 +341,8 @@ find_subframework_file (const char *fname, const char *pname)
 {
   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;
@@ -309,7 +352,7 @@ find_subframework_file (const char *fname, const char *pname)
   /* Subframework files must have / in the name.  */
   if (bufptr == 0)
     return 0;
-    
+
   fname_len = bufptr - fname;
   fast_dir = find_framework (fname, fname_len);
 
@@ -319,23 +362,23 @@ find_subframework_file (const char *fname, const char *pname)
   bufptr = strstr (pname, dot_framework);
 
   /* If the parent header is not of any framework, then this header
-     can not be part of any subframework.  */
+     cannot be part of any subframework.  */
   if (!bufptr)
     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);
 
@@ -351,18 +394,18 @@ find_subframework_file (const char *fname, const char *pname)
   /* 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);
@@ -385,7 +428,7 @@ add_system_framework_path (char *path)
   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;
@@ -403,7 +446,7 @@ add_framework_path (char *path)
 {
   cpp_dir *p;
 
-  p = xmalloc (sizeof (cpp_dir));
+  p = XNEW (cpp_dir);
   p->next = NULL;
   p->name = path;
   p->sysp = 0;
@@ -413,19 +456,61 @@ add_framework_path (char *path)
   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)
     {
@@ -434,8 +519,13 @@ darwin_register_frameworks (int 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);
        }
     }
 
@@ -449,7 +539,7 @@ darwin_register_frameworks (int stdinc)
    fails to find a header.  We search each file in the include stack,
    using FUNC, starting from the most deeply nested include and
    finishing with the main input file.  We stop searching when FUNC
-   returns non-zero.  */
+   returns nonzero.  */
 
 static const char*
 find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
@@ -477,4 +567,56 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
   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 1042.
+   Print a warning if the version number is not known.  */
+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')
+    {
+      if (darwin_macosx_version_min[4] != '.')
+       goto fail;
+      if (! ISDIGIT (darwin_macosx_version_min[5]))
+       goto fail;
+      if (darwin_macosx_version_min[6] != '\0')
+       goto fail;
+      result[3] = darwin_macosx_version_min[5];
+    }
+  else
+    result[3] = '0';
+
+  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);
+
+  if (darwin_macosx_version_min)
+    builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
+                              version_as_macro(), false);
+}