]> git.gag.com Git - fw/sdcc/commitdiff
* SDCPP synchronized with GCC CPP release version 4.2.0,
authorborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 1 Jun 2007 15:23:01 +0000 (15:23 +0000)
committerborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 1 Jun 2007 15:23:01 +0000 (15:23 +0000)
  currently the latest release:
* support/cpp2/c-incpath.c, support/cpp2/c-incpath.h,
  support/cpp2/c-ppoutput.c, support/cpp2/cppdefault.c,
  support/cpp2/cppdefault.h, support/cpp2/except.h,
  support/cpp2/libcpp/directives.c, support/cpp2/libcpp/expr.c,
  support/cpp2/libcpp/files.c, support/cpp2/libcpp/include/cpplib.h,
  support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h,
  support/cpp2/libcpp/lex.c, support/cpp2/libcpp/macro.c,
  support/cpp2/libcpp/mkdeps.c, support/cpp2/libiberty/getpwd.c,
  support/cpp2/libiberty/hashtab.c, support/cpp2/optc-gen.awk,
  support/cpp2/opth-gen.awk, support/cpp2/opts.c,
  support/cpp2/opts.h, support/cpp2/output.h,
  support/cpp2/prefix.c, support/cpp2/sdcpp-opts.c,
  support/cpp2/sdcpp.dsp, support/cpp2/sdcpp.opt,
  support/cpp2/system.h, support/cpp2/version.c: modified
* support/cpp2/opts-common.c: added

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4824 4a8a32a2-be11-0410-ad9d-d568d2c75423

30 files changed:
ChangeLog
support/cpp2/c-incpath.c
support/cpp2/c-incpath.h
support/cpp2/c-ppoutput.c
support/cpp2/cppdefault.c
support/cpp2/cppdefault.h
support/cpp2/except.h
support/cpp2/libcpp/directives.c
support/cpp2/libcpp/expr.c
support/cpp2/libcpp/files.c
support/cpp2/libcpp/include/cpplib.h
support/cpp2/libcpp/init.c
support/cpp2/libcpp/internal.h
support/cpp2/libcpp/lex.c
support/cpp2/libcpp/macro.c
support/cpp2/libcpp/mkdeps.c
support/cpp2/libiberty/getpwd.c
support/cpp2/libiberty/hashtab.c
support/cpp2/optc-gen.awk
support/cpp2/opth-gen.awk
support/cpp2/opts-common.c [new file with mode: 0644]
support/cpp2/opts.c
support/cpp2/opts.h
support/cpp2/output.h
support/cpp2/prefix.c
support/cpp2/sdcpp-opts.c
support/cpp2/sdcpp.dsp
support/cpp2/sdcpp.opt
support/cpp2/system.h
support/cpp2/version.c

index bf19116f674931c9c086ac7cf0c86be10b970388..18a169f3556440e2f106d8b855b42c87f5597efc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-06-01 Borut Razem <borut.razem AT siol.net>
+
+       * SDCPP synchronized with GCC CPP release version 4.2.0,
+         currently the latest release:
+       * support/cpp2/c-incpath.c, support/cpp2/c-incpath.h,
+         support/cpp2/c-ppoutput.c, support/cpp2/cppdefault.c,
+         support/cpp2/cppdefault.h, support/cpp2/except.h,
+         support/cpp2/libcpp/directives.c, support/cpp2/libcpp/expr.c,
+         support/cpp2/libcpp/files.c, support/cpp2/libcpp/include/cpplib.h,
+         support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h,
+         support/cpp2/libcpp/lex.c, support/cpp2/libcpp/macro.c,
+         support/cpp2/libcpp/mkdeps.c, support/cpp2/libiberty/getpwd.c,
+         support/cpp2/libiberty/hashtab.c, support/cpp2/optc-gen.awk,
+         support/cpp2/opth-gen.awk, support/cpp2/opts.c,
+         support/cpp2/opts.h, support/cpp2/output.h,
+         support/cpp2/prefix.c, support/cpp2/sdcpp-opts.c,
+         support/cpp2/sdcpp.dsp, support/cpp2/sdcpp.opt,
+         support/cpp2/system.h, support/cpp2/version.c: modified
+       * support/cpp2/opts-common.c: added
+
 2007-06-01 Raphael Neider <rneider AT web.de>
 
        * device/lib/pic/libdev/pic12f683.c,
index 014f8defd27d8d4348d761ea24770e7a260b2b83..3933dee241cffec039f97d8a2c4d46be5a1aedc4 100644 (file)
@@ -1,6 +1,7 @@
 /* Set up combined include path chain for the preprocessor.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
 
@@ -41,8 +42,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
 #endif
 
+static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
+
 static void add_env_var_paths (const char *, int);
-static void add_standard_paths (const char *, const char *, int);
+static void add_standard_paths (const char *, const char *, const char *, int);
 static void free_path (struct cpp_dir *, int);
 static void merge_include_chains (cpp_reader *, int);
 static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
@@ -105,7 +108,7 @@ add_env_var_paths (const char *env_var, int chain)
        path = xstrdup (".");
       else
        {
-         path = xmalloc (q - p + 1);
+         path = XNEWVEC (char, q - p + 1);
          memcpy (path, p, q - p);
          path[q - p] = '\0';
        }
@@ -116,7 +119,8 @@ add_env_var_paths (const char *env_var, int chain)
 
 /* Append the standard include chain defined in cppdefault.c.  */
 static void
-add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
+add_standard_paths (const char *sysroot, const char *iprefix,
+                   const char *imultilib, int cxx_stdinc)
 {
   const struct default_include *p;
   size_t len;
@@ -138,6 +142,8 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
              if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
                {
                  char *str = concat (iprefix, p->fname + len, NULL);
+                 if (p->multilib && imultilib)
+                   str = concat (str, dir_separator_str, imultilib, NULL);
                  add_path (str, SYSTEM, p->cxx_aware, false);
                }
            }
@@ -156,6 +162,9 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
          else
            str = update_path (p->fname, p->component);
 
+         if (p->multilib && imultilib)
+           str = concat (str, dir_separator_str, imultilib, NULL);
+
          add_path (str, SYSTEM, p->cxx_aware, false);
        }
     }
@@ -336,7 +345,7 @@ add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
     if (*c == '\\') *c = '/';
 #endif
 
-  p = xmalloc (sizeof (cpp_dir));
+  p = XNEW (cpp_dir);
   p->next = NULL;
   p->name = path;
   if (chain == SYSTEM || chain == AFTER)
@@ -353,8 +362,8 @@ add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
    removal, and registration with cpplib.  */
 void
 register_include_chains (cpp_reader *pfile, const char *sysroot,
-                        const char *iprefix, int stdinc, int cxx_stdinc,
-                        int verbose)
+                        const char *iprefix, const char *imultilib,
+                        int stdinc, int cxx_stdinc, int verbose)
 {
   static const char *const lang_env_vars[] =
     { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
@@ -376,7 +385,7 @@ register_include_chains (cpp_reader *pfile, const char *sysroot,
 
   /* Finally chain on the standard directories.  */
   if (stdinc)
-    add_standard_paths (sysroot, iprefix, cxx_stdinc);
+    add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc);
 
   target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
 
index c309844cf0add45b3e6b98817ae3b6190b74abed..3f268b79d57996754a0dd16f7b037781bc1fd83c 100644 (file)
@@ -1,5 +1,5 @@
 /* Set up combined include path for the preprocessor.
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -18,7 +18,8 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 extern void split_quote_chain (void);
 extern void add_path (char *, int, int, bool);
 extern void register_include_chains (cpp_reader *, const char *,
-                                    const char *, int, int, int);
+                                    const char *, const char *,
+                                    int, int, int);
 extern void add_cpp_dir_path (struct cpp_dir *, int);
 
 struct target_c_incpath_s {
index 30dbc077f09addc9911487b9b712d882356b02da..908558354adc9ee699ce8062800c945b5dc8d922 100644 (file)
@@ -245,7 +245,8 @@ print_line (source_location src_loc, const char *special_flags)
       const struct line_map *map = linemap_lookup (&line_table, src_loc);
 
       size_t to_file_len = strlen (map->to_file);
-      unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
+      unsigned char *to_file_quoted =
+         (unsigned char *) alloca (to_file_len * 4 + 1);
       unsigned char *p;
 
       print.src_line = SOURCE_LINE (map, src_loc);
@@ -322,7 +323,8 @@ cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node)
     fputs ((const char *) NODE_NAME (node), print.outf);
 
   putc ('\n', print.outf);
-  print.src_line++;
+  if (linemap_lookup (&line_table, line)->to_line != 0)
+    print.src_line++;
 }
 
 static void
@@ -367,7 +369,8 @@ void
 pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
 {
   size_t to_file_len = strlen (dir);
-  unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
+  unsigned char *to_file_quoted =
+     (unsigned char *) alloca (to_file_len * 4 + 1);
   unsigned char *p;
 
   /* cpp_quote_string does not nul-terminate, so we have to do it ourselves.  */
index 862ea12e9efff61cd19b2b2eb3db6c68f471af40..283742bff9e8b839f5f7425ab4d954bdb1b91ee1 100644 (file)
@@ -1,6 +1,6 @@
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -46,44 +46,44 @@ const struct default_include cpp_include_defaults[]
 = {
 #ifdef GPLUSPLUS_INCLUDE_DIR
     /* Pick up GNU C++ generic include files.  */
-    { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
+    { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0, 0 },
 #endif
 #ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
     /* Pick up GNU C++ target-dependent include files.  */
-    { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0 },
+    { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0, 1 },
 #endif
 #ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
     /* Pick up GNU C++ backward and deprecated include files.  */
-    { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0 },
+    { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0, 0 },
 #endif
 #ifdef LOCAL_INCLUDE_DIR
     /* /usr/local/include comes before the fixincluded header files.  */
-    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1 },
+    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 },
 #endif
 #ifdef PREFIX_INCLUDE_DIR
-    { PREFIX_INCLUDE_DIR, 0, 0, 1, 0 },
+    { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0 },
 #endif
 #ifdef GCC_INCLUDE_DIR
     /* This is the dir for fixincludes and for gcc's private headers.  */
-    { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
+    { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
 #endif
 #ifdef CROSS_INCLUDE_DIR
     /* One place the target system's headers might be.  */
-    { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
+    { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
 #endif
 #ifdef TOOL_INCLUDE_DIR
     /* Another place the target system's headers might be.  */
-    { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0 },
+    { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0, 0 },
 #endif
 #ifdef SYSTEM_INCLUDE_DIR
     /* Some systems have an extra dir of include files.  */
-    { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1 },
+    { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1, 0 },
 #endif
 #ifdef STANDARD_INCLUDE_DIR
     /* /usr/include comes dead last.  */
-    { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1 },
+    { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 0 },
 #endif
-    { 0, 0, 0, 0, 0 }
+    { 0, 0, 0, 0, 0, 0 }
   };
 #endif /* no INCLUDE_DEFAULTS */
 
index f5b38884de6e361084d4ca0a78e1c9beaf9e6d2a..a3a2416955475f1f5cfdcb16ce45d5b6fa371617 100644 (file)
@@ -1,6 +1,6 @@
 /* CPP Library.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -43,6 +43,9 @@ struct default_include
                                   C++.  */
   const char add_sysroot;      /* FNAME should be prefixed by
                                   cpp_SYSROOT.  */
+  const char multilib;         /* FNAME should have the multilib path
+                                  specified with -imultilib
+                                  appended.  */
 };
 
 extern const struct default_include cpp_include_defaults[];
index d5e391d9c77bbad3de31aa95681b6899160280d4..1f96477f2e0366d5320a368f73e08b4e0fd1b494 100644 (file)
@@ -52,7 +52,7 @@ extern bool can_throw_external_1 (int, bool);
 extern bool can_throw_external (rtx);
 
 /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls.  */
-extern void set_nothrow_function_flags (void);
+extern unsigned int set_nothrow_function_flags (void);
 
 /* After initial rtl generation, call back to finish generating
    exception support code.  */
@@ -65,7 +65,7 @@ extern rtx reachable_handlers (rtx);
 extern void maybe_remove_eh_handler (rtx);
 
 extern void convert_from_eh_region_ranges (void);
-extern void convert_to_eh_region_ranges (void);
+extern unsigned int convert_to_eh_region_ranges (void);
 extern void find_exception_handler_labels (void);
 extern bool current_function_has_exception_handlers (void);
 extern void output_function_exception_table (void);
@@ -82,7 +82,8 @@ extern rtx expand_builtin_extend_pointer (tree);
 extern rtx get_exception_pointer (struct function *);
 extern rtx get_exception_filter (struct function *);
 typedef tree (*duplicate_eh_regions_map) (tree, void *);
-extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, int);
+extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map,
+                                void *, int, int);
 
 extern void sjlj_emit_function_exit_after (rtx);
 extern void default_init_unwind_resume_libfunc (void);
@@ -106,6 +107,8 @@ extern void collect_eh_region_array (void);
 extern void expand_resx_expr (tree);
 extern void verify_eh_tree (struct function *);
 extern void dump_eh_tree (FILE *, struct function *);
+extern bool eh_region_outer_p (struct function *, int, int);
+extern int eh_region_outermost (struct function *, int, int);
 
 /* tree-eh.c */
 extern void add_stmt_to_eh_region_fn (struct function *, tree, int);
@@ -173,3 +176,7 @@ struct throw_stmt_node GTY(())
 
 extern struct htab *get_eh_throw_stmt_table (struct function *);
 extern void set_eh_throw_stmt_table (struct function *, struct htab *);
+
+#ifdef ENABLE_CHECKING
+extern void verify_eh_throw_table_statements (void);
+#endif
index ac2127ac9233a1de0ea614d42eca761e4307cf8b..7fb142e48c798354c3639695ea00472db6b540c8 100644 (file)
@@ -1,7 +1,6 @@
 /* CPP Library. (Directive handling.)
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Per Bothner, 1994-95.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -46,11 +45,13 @@ struct pragma_entry
   struct pragma_entry *next;
   const cpp_hashnode *pragma;  /* Name and length.  */
   bool is_nspace;
-  bool allow_expansion;
   bool is_internal;
+  bool is_deferred;
+  bool allow_expansion;
   union {
     pragma_cb handler;
     struct pragma_entry *space;
+    unsigned int ident;
   } u;
 };
 
@@ -106,13 +107,6 @@ static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
 static void do_include_common (cpp_reader *, enum include_type);
 static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
                                                  const cpp_hashnode *);
-static struct pragma_entry *insert_pragma_entry (cpp_reader *,
-                                                 struct pragma_entry **,
-                                                 const cpp_hashnode *,
-                                                 pragma_cb,
-                                                bool, bool);
-static void register_pragma (cpp_reader *, const char *, const char *,
-                            pragma_cb, bool, bool);
 static int count_registered_pragmas (struct pragma_entry *);
 static char ** save_registered_pragmas (struct pragma_entry *, char **);
 static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
@@ -278,7 +272,9 @@ start_directive (cpp_reader *pfile)
 static void
 end_directive (cpp_reader *pfile, int skip_line)
 {
-  if (CPP_OPTION (pfile, traditional))
+  if (pfile->state.in_deferred_pragma)
+    ;
+  else if (CPP_OPTION (pfile, traditional))
     {
       /* Revert change of prepare_directive_trad.  */
       pfile->state.prevent_expansion--;
@@ -491,9 +487,6 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
 {
   cpp_push_buffer (pfile, (const uchar *) buf, count,
                   /* from_stage3 */ true);
-  /* Disgusting hack.  */
-  if (dir_no == T_PRAGMA && pfile->buffer->prev)
-    pfile->buffer->file = pfile->buffer->prev->file;
   start_directive (pfile);
 
   /* This is a short-term fix to prevent a leading '#' being
@@ -505,8 +498,6 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
     prepare_directive_trad (pfile);
   pfile->directive->handler (pfile);
   end_directive (pfile, 1);
-  if (dir_no == T_PRAGMA)
-    pfile->buffer->file = NULL;
   _cpp_pop_buffer (pfile);
 }
 
@@ -1040,86 +1031,97 @@ lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma)
   return chain;
 }
 
-/* Create and insert a pragma entry for NAME at the beginning of a
-   singly-linked CHAIN.  If handler is NULL, it is a namespace,
-   otherwise it is a pragma and its handler.  If INTERNAL is true
-   this pragma is being inserted by libcpp itself. */
+/* Create and insert a blank pragma entry at the beginning of a
+   singly-linked CHAIN.  */
 static struct pragma_entry *
-insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
-                    const cpp_hashnode *pragma, pragma_cb handler,
-                    bool allow_expansion, bool internal)
+new_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain)
 {
   struct pragma_entry *new_entry;
 
   new_entry = (struct pragma_entry *)
     _cpp_aligned_alloc (pfile, sizeof (struct pragma_entry));
-  new_entry->pragma = pragma;
-  if (handler)
-    {
-      new_entry->is_nspace = 0;
-      new_entry->u.handler = handler;
-    }
-  else
-    {
-      new_entry->is_nspace = 1;
-      new_entry->u.space = NULL;
-    }
 
-  new_entry->allow_expansion = allow_expansion;
-  new_entry->is_internal = internal;
+  memset (new_entry, 0, sizeof (struct pragma_entry));
   new_entry->next = *chain;
+
   *chain = new_entry;
   return new_entry;
 }
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
-   goes in the global namespace.  HANDLER is the handler it will call,
-   which must be non-NULL.  If ALLOW_EXPANSION is set, allow macro
-   expansion while parsing pragma NAME.  INTERNAL is true if this is a
-   pragma registered by cpplib itself, false if it is registered via
-   cpp_register_pragma */
-static void
-register_pragma (cpp_reader *pfile, const char *space, const char *name,
-                pragma_cb handler, bool allow_expansion, bool internal)
+   goes in the global namespace.  */
+static struct pragma_entry *
+register_pragma_1 (cpp_reader *pfile, const char *space, const char *name,
+                  bool allow_name_expansion)
 {
   struct pragma_entry **chain = &pfile->pragmas;
   struct pragma_entry *entry;
   const cpp_hashnode *node;
 
-  if (!handler)
-    abort ();
-
   if (space)
     {
       node = cpp_lookup (pfile, U space, strlen (space));
       entry = lookup_pragma_entry (*chain, node);
       if (!entry)
-       entry = insert_pragma_entry (pfile, chain, node, NULL, 
-                                    allow_expansion, internal);
+       {
+         entry = new_pragma_entry (pfile, chain);
+         entry->pragma = node;
+         entry->is_nspace = true;
+         entry->allow_expansion = allow_name_expansion;
+       }
       else if (!entry->is_nspace)
        goto clash;
+      else if (entry->allow_expansion != allow_name_expansion)
+       {
+         cpp_error (pfile, CPP_DL_ICE,
+                    "registering pragmas in namespace \"%s\" with mismatched "
+                    "name expansion", space);
+         return NULL;
+       }
       chain = &entry->u.space;
     }
+  else if (allow_name_expansion)
+    {
+      cpp_error (pfile, CPP_DL_ICE,
+                "registering pragma \"%s\" with name expansion "
+                "and no namespace", name);
+      return NULL;
+    }
 
   /* Check for duplicates.  */
   node = cpp_lookup (pfile, U name, strlen (name));
   entry = lookup_pragma_entry (*chain, node);
-  if (entry)
+  if (entry == NULL)
     {
-      if (entry->is_nspace)
-       clash:
-       cpp_error (pfile, CPP_DL_ICE,
-                "registering \"%s\" as both a pragma and a pragma namespace",
-                NODE_NAME (node));
-      else if (space)
-       cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered",
-                  space, name);
-      else
-       cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
+      entry = new_pragma_entry (pfile, chain);
+      entry->pragma = node;
+      return entry;
     }
+
+  if (entry->is_nspace)
+    clash:
+    cpp_error (pfile, CPP_DL_ICE,
+              "registering \"%s\" as both a pragma and a pragma namespace",
+              NODE_NAME (node));
+  else if (space)
+    cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered",
+              space, name);
   else
-    insert_pragma_entry (pfile, chain, node, handler, allow_expansion, 
-                        internal);
+    cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
+
+  return NULL;
+}
+
+/* Register a cpplib internal pragma SPACE NAME with HANDLER.  */
+static void
+register_pragma_internal (cpp_reader *pfile, const char *space,
+                         const char *name, pragma_cb handler)
+{
+  struct pragma_entry *entry;
+
+  entry = register_pragma_1 (pfile, space, name, false);
+  entry->is_internal = true;
+  entry->u.handler = handler;
 }
 
 /* Register a pragma NAME in namespace SPACE.  If SPACE is null, it
@@ -1131,22 +1133,53 @@ void
 cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
                     pragma_cb handler, bool allow_expansion)
 {
-  register_pragma (pfile, space, name, handler, allow_expansion, false);
+  struct pragma_entry *entry;
+
+  if (!handler)
+    {
+      cpp_error (pfile, CPP_DL_ICE, "registering pragma with NULL handler");
+      return;
+    }
+
+  entry = register_pragma_1 (pfile, space, name, false);
+  if (entry)
+    {
+      entry->allow_expansion = allow_expansion;
+      entry->u.handler = handler;
+    }
 }
 
+/* Similarly, but create mark the pragma for deferred processing.
+   When found, a CPP_PRAGMA token will be insertted into the stream
+   with IDENT in the token->u.pragma slot.  */
+void
+cpp_register_deferred_pragma (cpp_reader *pfile, const char *space,
+                             const char *name, unsigned int ident,
+                             bool allow_expansion, bool allow_name_expansion)
+{
+  struct pragma_entry *entry;
+
+  entry = register_pragma_1 (pfile, space, name, allow_name_expansion);
+  if (entry)
+    {
+      entry->is_deferred = true;
+      entry->allow_expansion = allow_expansion;
+      entry->u.ident = ident;
+    }
+}  
+
 /* Register the pragmas the preprocessor itself handles.  */
 void
 _cpp_init_internal_pragmas (cpp_reader *pfile)
 {
   /* Pragmas in the global namespace.  */
-  register_pragma (pfile, 0, "once", do_pragma_once, false, true);
+  register_pragma_internal (pfile, 0, "once", do_pragma_once);
 
   /* New GCC-specific pragmas should be put in the GCC namespace.  */
-  register_pragma (pfile, "GCC", "poison", do_pragma_poison, false, true);
-  register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, 
-                  false, true);
-  register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, 
-                  false, true);
+  register_pragma_internal (pfile, "GCC", "poison", do_pragma_poison);
+  register_pragma_internal (pfile, "GCC", "system_header",
+                           do_pragma_system_header);
+  register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency);
 }
 
 /* Return the number of registered pragmas in PE.  */
@@ -1224,130 +1257,85 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved)
    front end.  C99 defines three pragmas and says that no macro
    expansion is to be performed on them; whether or not macro
    expansion happens for other pragmas is implementation defined.
-   This implementation never macro-expands the text after #pragma.
-
-   The library user has the option of deferring execution of
-   #pragmas not handled by cpplib, in which case they are converted
-   to CPP_PRAGMA tokens and inserted into the output stream.  */
+   This implementation allows for a mix of both, since GCC did not
+   traditionally macro expand its (few) pragmas, whereas OpenMP
+   specifies that macro expansion should happen.  */
 static void
 do_pragma (cpp_reader *pfile)
 {
   const struct pragma_entry *p = NULL;
   const cpp_token *token, *pragma_token = pfile->cur_token;
+  cpp_token ns_token;
   unsigned int count = 1;
 
-  /* Save the current position so that defer_pragmas mode can
-     copy the entire current line to a string.  It will not work
-     to use _cpp_backup_tokens as that does not reverse buffer->cur.  */
-  const uchar *line_start = CPP_BUFFER (pfile)->cur;
-
   pfile->state.prevent_expansion++;
 
   token = cpp_get_token (pfile);
+  ns_token = *token;
   if (token->type == CPP_NAME)
     {
       p = lookup_pragma_entry (pfile->pragmas, token->val.node);
       if (p && p->is_nspace)
        {
-         count = 2;
+         bool allow_name_expansion = p->allow_expansion;
+         if (allow_name_expansion)
+           pfile->state.prevent_expansion--;
          token = cpp_get_token (pfile);
          if (token->type == CPP_NAME)
            p = lookup_pragma_entry (p->u.space, token->val.node);
          else
            p = NULL;
+         if (allow_name_expansion)
+           pfile->state.prevent_expansion++;
+         count = 2;
        }
     }
 
   if (p)
     {
-      if (p->is_internal || !CPP_OPTION (pfile, defer_pragmas))
+      if (p->is_deferred)
+       {
+         pfile->directive_result.src_loc = pragma_token->src_loc;
+         pfile->directive_result.type = CPP_PRAGMA;
+         pfile->directive_result.flags = pragma_token->flags;
+         pfile->directive_result.val.pragma = p->u.ident;
+         pfile->state.in_deferred_pragma = true;
+         pfile->state.pragma_allow_expansion = p->allow_expansion;
+         if (!p->allow_expansion)
+           pfile->state.prevent_expansion++;
+       }
+      else
        {
-         /* Since the handler below doesn't get the line number, that it
-            might need for diagnostics, make sure it has the right
+         /* Since the handler below doesn't get the line number, that
+            it might need for diagnostics, make sure it has the right
             numbers in place.  */
          if (pfile->cb.line_change)
            (*pfile->cb.line_change) (pfile, pragma_token, false);
-         /* Never expand macros if handling a deferred pragma, since
-            the macro definitions now applicable may be different
-            from those at the point the pragma appeared.  */
-         if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+         if (p->allow_expansion)
            pfile->state.prevent_expansion--;
          (*p->u.handler) (pfile);
-         if (p->allow_expansion && !pfile->state.in_deferred_pragma)
+         if (p->allow_expansion)
            pfile->state.prevent_expansion++;
        }
-      else
-       {
-         /* Squirrel away the pragma text.  Pragmas are
-            newline-terminated. */
-         const uchar *line_end;
-         uchar *s, c, cc;
-         cpp_string body;
-         cpp_token *ptok;
-
-         for (line_end = line_start; (c = *line_end) != '\n'; line_end++)
-           if (c == '"' || c == '\'')
-             {
-               /* Skip over string literal.  */
-               do
-                 {
-                   cc = *++line_end;
-                   if (cc == '\\' && line_end[1] != '\n')
-                     line_end++;
-                   else if (cc == '\n')
-                     {
-                       line_end--;
-                       break;
-                     }
-                 }
-               while (cc != c);
-             }
-           else if (c == '/')
-             {
-               if (line_end[1] == '*')
-                 {
-                   /* Skip over C block comment, unless it is multi-line.
-                      When encountering multi-line block comment, terminate
-                      the pragma token right before that block comment.  */
-                   const uchar *le = line_end + 2;
-                   while (*le != '\n')
-                     if (*le++ == '*' && *le == '/')
-                       {
-                         line_end = le;
-                         break;
-                       }
-                   if (line_end < le)
-                     break;
-                 }
-               else if (line_end[1] == '/'
-                        && (CPP_OPTION (pfile, cplusplus_comments)
-                            || cpp_in_system_header (pfile)))
-                 {
-                   line_end += 2;
-                   while (*line_end != '\n')
-                     line_end++;
-                   break;
-                 }
-             }
-
-         body.len = (line_end - line_start) + 1;
-         s = _cpp_unaligned_alloc (pfile, body.len + 1);
-         memcpy (s, line_start, body.len - 1);
-         s[body.len - 1] = '\n';
-         s[body.len] = '\0';
-         body.text = s;
-
-         /* Create a CPP_PRAGMA token.  */
-         ptok = &pfile->directive_result;
-         ptok->src_loc = pragma_token->src_loc;
-         ptok->type = CPP_PRAGMA;
-         ptok->flags = pragma_token->flags | NO_EXPAND;
-         ptok->val.str = body;
-       }
     }
   else if (pfile->cb.def_pragma)
     {
-      _cpp_backup_tokens (pfile, count);
+      if (count == 1 || pfile->context->prev == NULL)
+       _cpp_backup_tokens (pfile, count);
+      else
+       {
+         /* Invalid name comes from macro expansion, _cpp_backup_tokens
+            won't allow backing 2 tokens.  */
+         /* ??? The token buffer is leaked.  Perhaps if def_pragma hook
+            reads both tokens, we could perhaps free it, but if it doesn't,
+            we don't know the exact lifespan.  */
+         cpp_token *toks = XNEWVEC (cpp_token, 2);
+         toks[0] = ns_token;
+         toks[0].flags |= NO_EXPAND;
+         toks[1] = *token;
+         toks[1].flags |= NO_EXPAND;
+         _cpp_push_token_context (pfile, NULL, toks, 2);
+       }
       pfile->cb.def_pragma (pfile, pfile->directive_line);
     }
 
@@ -1490,6 +1478,11 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
 {
   const unsigned char *src, *limit;
   char *dest, *result;
+  cpp_context *saved_context;
+  cpp_token *saved_cur_token;
+  tokenrun *saved_cur_run;
+  cpp_token *toks;
+  int count;
 
   dest = result = (char *) alloca (in->len - 1);
   src = in->text + 1 + (in->text[0] == 'L');
@@ -1511,36 +1504,85 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
 
      Something like line-at-a-time lexing should remove the need for
      this.  */
-  {
-    cpp_context *saved_context = pfile->context;
-    cpp_token *saved_cur_token = pfile->cur_token;
-    tokenrun *saved_cur_run = pfile->cur_run;
-
-    pfile->context = XNEW (cpp_context);
-    pfile->context->macro = 0;
-    pfile->context->prev = 0;
-    run_directive (pfile, T_PRAGMA, result, dest - result);
-    XDELETE (pfile->context);
-    pfile->context = saved_context;
-    pfile->cur_token = saved_cur_token;
-    pfile->cur_run = saved_cur_run;
-  }
+  saved_context = pfile->context;
+  saved_cur_token = pfile->cur_token;
+  saved_cur_run = pfile->cur_run;
 
-  /* See above comment.  For the moment, we'd like
+  pfile->context = XNEW (cpp_context);
+  pfile->context->macro = 0;
+  pfile->context->prev = 0;
+  pfile->context->next = 0;
+
+  /* Inline run_directive, since we need to delay the _cpp_pop_buffer
+     until we've read all of the tokens that we want.  */
+  cpp_push_buffer (pfile, (const uchar *) result, dest - result,
+                  /* from_stage3 */ true);
+  /* ??? Antique Disgusting Hack.  What does this do?  */
+  if (pfile->buffer->prev)
+    pfile->buffer->file = pfile->buffer->prev->file;
 
-     token1 _Pragma ("foo") token2
+  start_directive (pfile);
+  _cpp_clean_line (pfile);
+  do_pragma (pfile);
+  end_directive (pfile, 1);
 
-     to be output as
+  /* We always insert at least one token, the directive result.  It'll
+     either be a CPP_PADDING or a CPP_PRAGMA.  In the later case, we 
+     need to insert *all* of the tokens, including the CPP_PRAGMA_EOL.  */
+
+  /* If we're not handling the pragma internally, read all of the tokens from
+     the string buffer now, while the string buffer is still installed.  */
+  /* ??? Note that the token buffer allocated here is leaked.  It's not clear
+     to me what the true lifespan of the tokens are.  It would appear that
+     the lifespan is the entire parse of the main input stream, in which case
+     this may not be wrong.  */
+  if (pfile->directive_result.type == CPP_PRAGMA)
+    {
+      int maxcount;
 
-               token1
-               # 7 "file.c"
-               #pragma foo
-               # 7 "file.c"
-                              token2
+      count = 1;
+      maxcount = 50;
+      toks = XNEWVEC (cpp_token, maxcount);
+      toks[0] = pfile->directive_result;
 
-      Getting the line markers is a little tricky.  */
-  if (pfile->cb.line_change)
-    pfile->cb.line_change (pfile, pfile->cur_token, false);
+      do
+       {
+         if (count == maxcount)
+           {
+             maxcount = maxcount * 3 / 2;
+             toks = XRESIZEVEC (cpp_token, toks, maxcount);
+           }
+         toks[count] = *cpp_get_token (pfile);
+         /* Macros have been already expanded by cpp_get_token
+            if the pragma allowed expansion.  */
+         toks[count++].flags |= NO_EXPAND;
+       }
+      while (toks[count-1].type != CPP_PRAGMA_EOL);
+    }
+  else
+    {
+      count = 1;
+      toks = XNEW (cpp_token);
+      toks[0] = pfile->directive_result;
+
+      /* If we handled the entire pragma internally, make sure we get the
+        line number correct for the next token.  */
+      if (pfile->cb.line_change)
+       pfile->cb.line_change (pfile, pfile->cur_token, false);
+    }
+
+  /* Finish inlining run_directive.  */
+  pfile->buffer->file = NULL;
+  _cpp_pop_buffer (pfile);
+
+  /* Reset the old macro state before ...  */
+  XDELETE (pfile->context);
+  pfile->context = saved_context;
+  pfile->cur_token = saved_cur_token;
+  pfile->cur_run = saved_cur_run;
+
+  /* ... inserting the new tokens we collected.  */
+  _cpp_push_token_context (pfile, NULL, toks, count);
 }
 
 /* Handle the _Pragma operator.  */
@@ -1557,35 +1599,6 @@ _cpp_do__Pragma (cpp_reader *pfile)
               "_Pragma takes a parenthesized string literal");
 }
 
-/* Handle a pragma that the front end deferred until now. */
-void
-cpp_handle_deferred_pragma (cpp_reader *pfile, const cpp_string *s)
-{
-  cpp_context *saved_context = pfile->context;
-  cpp_token *saved_cur_token = pfile->cur_token;
-  tokenrun *saved_cur_run = pfile->cur_run;
-  bool saved_defer_pragmas = CPP_OPTION (pfile, defer_pragmas);
-  void (*saved_line_change) (cpp_reader *, const cpp_token *, int)
-    = pfile->cb.line_change;
-
-  pfile->context = XNEW (cpp_context);
-  pfile->context->macro = 0;
-  pfile->context->prev = 0;
-  pfile->cb.line_change = NULL;
-  pfile->state.in_deferred_pragma = true;
-  CPP_OPTION (pfile, defer_pragmas) = false;
-
-  run_directive (pfile, T_PRAGMA, (const char *)s->text, s->len);
-
-  XDELETE (pfile->context);
-  pfile->context = saved_context;
-  pfile->cur_token = saved_cur_token;
-  pfile->cur_run = saved_cur_run;
-  pfile->cb.line_change = saved_line_change;
-  pfile->state.in_deferred_pragma = false;
-  CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas;
-}
-
 /* Handle #ifdef.  */
 static void
 do_ifdef (cpp_reader *pfile)
index 32b1723830987651451012d7c396c32ecf60dbde..574b85ff656dd02b97dfd27f1c292ec6eea19a4e 100644 (file)
@@ -82,7 +82,7 @@ static void check_promotion (cpp_reader *, const struct op *);
 static unsigned int
 interpret_float_suffix (const uchar *s, size_t len)
 {
-  size_t f = 0, l = 0, i = 0;
+  size_t f = 0, l = 0, i = 0, d = 0;
 
   while (len--)
     switch (s[len])
@@ -91,6 +91,12 @@ interpret_float_suffix (const uchar *s, size_t len)
       case 'l': case 'L': l++; break;
       case 'i': case 'I':
       case 'j': case 'J': i++; break;
+      case 'd': case 'D': 
+       /* Disallow fd, ld suffixes.  */
+       if (d && (f || l))
+         return 0;
+       d++;
+       break;
       default:
        return 0;
       }
@@ -98,9 +104,14 @@ interpret_float_suffix (const uchar *s, size_t len)
   if (f + l > 1 || i > 1)
     return 0;
 
+  /* Allow dd, df, dl suffixes for decimal float constants.  */
+  if (d && ((d + f + l != 2) || i))
+    return 0;
+
   return ((i ? CPP_N_IMAGINARY : 0)
          | (f ? CPP_N_SMALL :
-            l ? CPP_N_LARGE : CPP_N_MEDIUM));
+            l ? CPP_N_LARGE : CPP_N_MEDIUM)
+         | (d ? CPP_N_DFLOAT : 0));
 }
 
 /* Subroutine of cpp_classify_number.  S points to an integer suffix
@@ -250,6 +261,15 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
                   "traditional C rejects the \"%.*s\" suffix",
                   (int) (limit - str), str);
 
+      /* Radix must be 10 for decimal floats.  */
+      if ((result & CPP_N_DFLOAT) && radix != 10)
+        {
+          cpp_error (pfile, CPP_DL_ERROR,
+                     "invalid suffix \"%.*s\" with hexadecimal floating constant",
+                     (int) (limit - str), str);
+          return CPP_N_INVALID;
+        }
+
       result |= CPP_N_FLOATING;
     }
   else
@@ -648,9 +668,6 @@ static const struct cpp_operator
   /* RSHIFT */         {13, LEFT_ASSOC},
   /* LSHIFT */         {13, LEFT_ASSOC},
 
-  /* MIN */            {10, LEFT_ASSOC | CHECK_PROMOTION},
-  /* MAX */            {10, LEFT_ASSOC | CHECK_PROMOTION},
-
   /* COMPL */          {16, NO_L_OPERAND},
   /* AND_AND */                {6, LEFT_ASSOC},
   /* OR_OR */          {5, LEFT_ASSOC},
@@ -862,8 +879,6 @@ reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
        case CPP_MINUS:
        case CPP_RSHIFT:
        case CPP_LSHIFT:
-       case CPP_MIN:
-       case CPP_MAX:
        case CPP_COMMA:
          top[-1].value = num_binary_op (pfile, top[-1].value,
                                         top->value, top->op);
@@ -1289,7 +1304,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
 {
   cpp_num result;
   size_t precision = CPP_OPTION (pfile, precision);
-  bool gte;
   size_t n;
 
   switch (op)
@@ -1316,21 +1330,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
        lhs = num_rshift (lhs, precision, n);
       break;
 
-      /* Min / Max.  */
-    case CPP_MIN:
-    case CPP_MAX:
-      {
-       bool unsignedp = lhs.unsignedp || rhs.unsignedp;
-
-       gte = num_greater_eq (lhs, rhs, precision);
-       if (op == CPP_MIN)
-         gte = !gte;
-       if (!gte)
-         lhs = rhs;
-       lhs.unsignedp = unsignedp;
-      }
-      break;
-
       /* Arithmetic.  */
     case CPP_MINUS:
       rhs = num_negate (rhs, precision);
index 702aa4c8688f052cf643aa28a3d66e64d453b4fb..57643822e93a40a7b2f7fcfe1e860a38a419770d 100644 (file)
@@ -1158,6 +1158,13 @@ _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file)
     }
 }
 
+/* Inteface to file statistics record in _cpp_file structure. */
+struct stat *
+_cpp_get_file_stat (_cpp_file *file)
+{
+    return &file->st;
+}
+
 /* Set the include chain for "" to QUOTE, for <> to BRACKET.  If
    QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the
    directory of the including file.
index 4e879b9d341f9249ed91d58ceafe0803f3b39266..dc02b6b7cb3c33d66af410f266d5e58c41e52210 100644 (file)
@@ -51,7 +51,10 @@ struct _cpp_file;
 
    The first group, to CPP_LAST_EQ, can be immediately followed by an
    '='.  The lexer needs operators ending in '=', like ">>=", to be in
-   the same order as their counterparts without the '=', like ">>".  */
+   the same order as their counterparts without the '=', like ">>".
+
+   See the cpp_operator table optab in expr.c if you change the order or
+   add or remove anything in the first group.  */
 
 #define TTYPE_TABLE                                                    \
   OP(EQ,               "=")                                            \
@@ -68,8 +71,6 @@ struct _cpp_file;
   OP(XOR,              "^")                                            \
   OP(RSHIFT,           ">>")                                           \
   OP(LSHIFT,           "<<")                                           \
-  OP(MIN,              "<?")   /* extension */                         \
-  OP(MAX,              ">?")                                           \
                                                                        \
   OP(COMPL,            "~")                                            \
   OP(AND_AND,          "&&")   /* logical */                           \
@@ -97,8 +98,6 @@ struct _cpp_file;
   OP(XOR_EQ,           "^=")                                           \
   OP(RSHIFT_EQ,                ">>=")                                          \
   OP(LSHIFT_EQ,                "<<=")                                          \
-  OP(MIN_EQ,           "<?=")  /* extension */                         \
-  OP(MAX_EQ,           ">?=")                                          \
   /* Digraphs together, beginning with CPP_FIRST_DIGRAPH.  */          \
   OP(HASH,             "#")    /* digraphs */                          \
   OP(PASTE,            "##")                                           \
@@ -134,7 +133,8 @@ struct _cpp_file;
   TK(COMMENT,          LITERAL) /* Only if output comments.  */        \
                                 /* SPELL_LITERAL happens to DTRT.  */  \
   TK(MACRO_ARG,                NONE)    /* Macro argument.  */                 \
-  TK(PRAGMA,           NONE)    /* Only if deferring pragmas */        \
+  TK(PRAGMA,           NONE)    /* Only for deferred pragmas.  */      \
+  TK(PRAGMA_EOL,       NONE)    /* End-of-line for deferred pragmas.  */ \
   TK(PADDING,          NONE)    /* Whitespace for -E.  */              \
 \
   /* SDCC _asm specific */                                             \
@@ -148,9 +148,9 @@ enum cpp_ttype
   N_TTYPES,
 
   /* Positions in the table.  */
-  CPP_LAST_EQ        = CPP_MAX,
+  CPP_LAST_EQ        = CPP_LSHIFT,
   CPP_FIRST_DIGRAPH  = CPP_HASH,
-  CPP_LAST_PUNCTUATOR= CPP_DOT_STAR,
+  CPP_LAST_PUNCTUATOR= CPP_ATSIGN,
   CPP_LAST_CPP_OP    = CPP_LESS_EQ
 };
 #undef OP
@@ -175,6 +175,8 @@ struct cpp_string GTY(())
 #define NAMED_OP       (1 << 4) /* C++ named operators.  */
 #define NO_EXPAND      (1 << 5) /* Do not macro-expand this token.  */
 #define BOL            (1 << 6) /* Token at beginning of line.  */
+#define PURE_ZERO      (1 << 7) /* Single 0 digit, used by the C++ frontend,
+                                   set in c-lex.c.  */
 
 /* Specify which field, if any, of the cpp_token union is used.  */
 
@@ -183,6 +185,7 @@ enum cpp_token_fld_kind {
   CPP_TOKEN_FLD_SOURCE,
   CPP_TOKEN_FLD_STR,
   CPP_TOKEN_FLD_ARG_NO,
+  CPP_TOKEN_FLD_PRAGMA,
   CPP_TOKEN_FLD_NONE
 };
 
@@ -212,6 +215,9 @@ struct cpp_token GTY(())
 
     /* Argument no. for a CPP_MACRO_ARG.  */
     unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no;
+
+    /* Caller-supplied identifier for a CPP_PRAGMA.  */
+    unsigned int GTY ((tag ("CPP_TOKEN_FLD_PRAGMA"))) pragma;
   } GTY ((desc ("cpp_token_val_index (&%1)"))) val;
 };
 
@@ -452,10 +458,6 @@ struct cpp_options
   /* Nonzero means __STDC__ should have the value 0 in system headers.  */
   unsigned char stdc_0_in_system_headers;
 
-  /* True means return pragmas as tokens rather than processing
-     them directly. */
-  bool defer_pragmas;
-
   /* True means error callback should be used for diagnostics.  */
   bool client_diagnostic;
 };
@@ -572,7 +574,8 @@ enum builtin_type
   BT_INCLUDE_LEVEL,            /* `__INCLUDE_LEVEL__' */
   BT_TIME,                     /* `__TIME__' */
   BT_STDC,                     /* `__STDC__' */
-  BT_PRAGMA                    /* `_Pragma' operator */
+  BT_PRAGMA,                   /* `_Pragma' operator */
+  BT_TIMESTAMP                 /* `__TIMESTAMP__' */
 };
 
 #define CPP_HASHNODE(HNODE)    ((cpp_hashnode *) (HNODE))
@@ -691,7 +694,8 @@ extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
                                       unsigned char *, bool);
 extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
                                 void (*) (cpp_reader *), bool);
-extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *);
+extern void cpp_register_deferred_pragma (cpp_reader *, const char *,
+                                         const char *, unsigned, bool, bool);
 extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
                            const cpp_token *);
 extern const cpp_token *cpp_get_token (cpp_reader *);
@@ -763,6 +767,7 @@ struct cpp_num
 
 #define CPP_N_UNSIGNED 0x1000  /* Properties.  */
 #define CPP_N_IMAGINARY        0x2000
+#define CPP_N_DFLOAT   0x4000
 
 /* Classify a CPP_NUMBER token.  The return value is a combination of
    the flags from the above sets.  */
index b05441153dd2be56deabe61734773c0b1c0f2ef6..20e4545c27993c686dfee26e4d292ffd5871eb63 100644 (file)
@@ -303,6 +303,7 @@ struct builtin
 #define B(n, t)    { DSC(n), t }
 static const struct builtin builtin_array[] =
 {
+  B("__TIMESTAMP__",    BT_TIMESTAMP),
   B("__TIME__",                 BT_TIME),
   B("__DATE__",                 BT_DATE),
   B("__FILE__",                 BT_FILE),
index 960f153e4dc4815d3755448c0a75facb75affb50..d8e07e388981efd5b74040b6e3af7aca5cae5f74 100644 (file)
@@ -205,9 +205,6 @@ struct lexer_state
   /* Nonzero to prevent macro expansion.  */
   unsigned char prevent_expansion;
 
-  /* Nonzero when handling a deferred pragma.  */
-  unsigned char in_deferred_pragma;
-
   /* Nonzero when parsing arguments to a function-like macro.  */
   unsigned char parsing_args;
 
@@ -217,6 +214,12 @@ struct lexer_state
 
   /* Nonzero to skip evaluating part of an expression.  */
   unsigned int skip_eval;
+
+  /* Nonzero when handling a deferred pragma.  */
+  unsigned char in_deferred_pragma;
+
+  /* Nonzero if the deferred pragma being handled allows macro expansion.  */
+  unsigned char pragma_allow_expansion;
 };
 
 /* Special nodes - identifiers with predefined significance.  */
@@ -263,6 +266,10 @@ struct cpp_buffer
      Used for include_next and to record control macros.  */
   struct _cpp_file *file;
 
+  /* Saved value of __TIMESTAMP__ macro - date and time of last modification
+     of the assotiated file.  */
+  const unsigned char *timestamp;
+
   /* Value of if_stack at start of this file.
      Used to prohibit unmatched #endif (etc) in an include file.  */
   struct if_stack *if_stack;
@@ -498,7 +505,10 @@ extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *,
                               unsigned int);
 extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *,
                                                     cpp_hashnode *);
-int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
+extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
+extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *,
+                                    const cpp_token *, unsigned int);
+
 /* In identifiers.c */
 extern void _cpp_init_hashtable (cpp_reader *, hash_table *);
 extern void _cpp_destroy_hashtable (cpp_reader *);
@@ -520,6 +530,7 @@ extern void _cpp_cleanup_files (cpp_reader *);
 extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *);
 extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f);
 extern bool _cpp_read_file_entries (cpp_reader *, FILE *);
+extern struct stat *_cpp_get_file_stat (_cpp_file *);
 
 /* In expr.c */
 extern bool _cpp_parse_expr (cpp_reader *);
index be96d97b39498864a59d4b8a7436d7a5ab0804c7..22dc7e7e54149d1f67d92ed41bab98596e4d76fa 100644 (file)
@@ -937,6 +937,10 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
     cpp_error (pfile, CPP_DL_WARNING,
               "null character(s) preserved in literal");
 
+  if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM)
+    cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character",
+              (int) terminator);
+
   pfile->buffer->cur = cur;
   create_literal (pfile, token, base, cur - base, type);
 }
@@ -1111,24 +1115,24 @@ _cpp_lex_token (cpp_reader *pfile)
              /* 6.10.3 p 11: Directives in a list of macro arguments
                 gives undefined behavior.  This implementation
                 handles the directive as normal.  */
-             && pfile->state.parsing_args != 1
-             && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
+             && pfile->state.parsing_args != 1)
            {
-             if (pfile->directive_result.type == CPP_PADDING)
-               continue;
-             else
+             if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
                {
+                 if (pfile->directive_result.type == CPP_PADDING)
+                   continue;
                  result = &pfile->directive_result;
-                 break;
                }
            }
+         else if (pfile->state.in_deferred_pragma)
+           result = &pfile->directive_result;
 
          if (pfile->cb.line_change && !pfile->state.skipping)
            pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
        }
 
       /* We don't skip tokens in directives.  */
-      if (pfile->state.in_directive)
+      if (pfile->state.in_directive || pfile->state.in_deferred_pragma)
        break;
 
       /* Outside a directive, invalidate controlling macros.  At file
@@ -1222,6 +1226,14 @@ _cpp_lex_direct (cpp_reader *pfile)
   buffer = pfile->buffer;
   if (buffer->need_line)
     {
+      if (pfile->state.in_deferred_pragma)
+       {
+         result->type = CPP_PRAGMA_EOL;
+         pfile->state.in_deferred_pragma = false;
+         if (!pfile->state.pragma_allow_expansion)
+           pfile->state.prevent_expansion--;
+         return result;
+       }
       if (!_cpp_get_fresh_line (pfile))
        {
          result->type = CPP_EOF;
@@ -1401,11 +1413,6 @@ _cpp_lex_direct (cpp_reader *pfile)
          buffer->cur++;
          IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT);
        }
-      else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus))
-       {
-         buffer->cur++;
-         IF_NEXT_IS ('=', CPP_MIN_EQ, CPP_MIN);
-       }
       else if (CPP_OPTION (pfile, digraphs))
        {
          if (*buffer->cur == ':')
@@ -1432,11 +1439,6 @@ _cpp_lex_direct (cpp_reader *pfile)
          buffer->cur++;
          IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT);
        }
-      else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus))
-       {
-         buffer->cur++;
-         IF_NEXT_IS ('=', CPP_MAX_EQ, CPP_MAX);
-       }
       break;
 
     case '%':
@@ -1824,8 +1826,8 @@ cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1,
 
   switch (a)
     {
-    case CPP_GREATER:  return c == '>' || c == '?';
-    case CPP_LESS:     return c == '<' || c == '?' || c == '%' || c == ':';
+    case CPP_GREATER:  return c == '>';
+    case CPP_LESS:     return c == '<' || c == '%' || c == ':';
     case CPP_PLUS:     return c == '+';
     case CPP_MINUS:    return c == '-' || c == '>';
     case CPP_DIV:      return c == '/' || c == '*'; /* Comments.  */
@@ -2057,7 +2059,7 @@ cpp_token_val_index (cpp_token *tok)
       else if (tok->type == CPP_PADDING)
        return CPP_TOKEN_FLD_SOURCE;
       else if (tok->type == CPP_PRAGMA)
-       return CPP_TOKEN_FLD_STR;
+       return CPP_TOKEN_FLD_PRAGMA;
       /* else fall through */
     default:
       return CPP_TOKEN_FLD_NONE;
index b4143110af97121e10c9e770164169dac06eb5cc..c33b7fce2fdad591a99d37f20843e7f00df502e8 100644 (file)
@@ -42,8 +42,6 @@ struct macro_arg
 
 static int enter_macro_context (cpp_reader *, cpp_hashnode *);
 static int builtin_macro (cpp_reader *, cpp_hashnode *);
-static void push_token_context (cpp_reader *, cpp_hashnode *,
-                               const cpp_token *, unsigned int);
 static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
                                 const cpp_token **, unsigned int);
 static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *);
@@ -125,6 +123,44 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
                 NODE_NAME (node));
       break;
 
+    case BT_TIMESTAMP:
+      {
+       cpp_buffer *pbuffer = cpp_get_buffer (pfile);
+       if (pbuffer->timestamp == NULL)
+         {
+           /* Initialize timestamp value of the assotiated file. */
+            struct _cpp_file *file = cpp_get_file (pbuffer);
+           if (file)
+             {
+               /* Generate __TIMESTAMP__ string, that represents 
+                  the date and time of the last modification 
+                  of the current source file. The string constant 
+                  looks like "Sun Sep 16 01:03:52 1973".  */
+               struct tm *tb = NULL;
+               struct stat *st = _cpp_get_file_stat (file);
+               if (st)
+                 tb = localtime (&st->st_mtime);
+               if (tb)
+                 {
+                   char *str = asctime (tb);
+                   size_t len = strlen (str);
+                   unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2);
+                   buf[0] = '"';
+                   strcpy ((char *) buf + 1, str);
+                   buf[len] = '"';
+                   pbuffer->timestamp = buf;
+                 }
+               else
+                 {
+                   cpp_errno (pfile, CPP_DL_WARNING,
+                       "could not determine file timestamp");
+                   pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\"";
+                 }
+             }
+         }
+       result = pbuffer->timestamp;
+      }
+      break;
     case BT_FILE:
     case BT_BASE_FILE:
       {
@@ -257,13 +293,6 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
        return 0;
 
       _cpp_do__Pragma (pfile);
-      if (pfile->directive_result.type == CPP_PRAGMA)
-       {
-         cpp_token *tok = _cpp_temp_token (pfile);
-         *tok = pfile->directive_result;
-         push_token_context (pfile, NULL, tok, 1);
-       }
-
       return 1;
     }
 
@@ -278,7 +307,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
 
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
-  push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
+  _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
   if (pfile->buffer->cur != pfile->buffer->rlimit)
     cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
               NODE_NAME (node));
@@ -401,15 +430,14 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg)
 static bool
 paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
 {
-  unsigned char *buf, *end;
+  unsigned char *buf, *end, *lhsend;
   const cpp_token *lhs;
   unsigned int len;
-  bool valid;
 
   lhs = *plhs;
   len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
   buf = (unsigned char *) alloca (len);
-  end = cpp_spell_token (pfile, lhs, buf, false);
+  end = lhsend = cpp_spell_token (pfile, lhs, buf, false);
 
   /* Avoid comment headers, since they are still processed in stage 3.
      It is simpler to insert a space here, rather than modifying the
@@ -426,10 +454,22 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
   /* Set pfile->cur_token as required by _cpp_lex_direct.  */
   pfile->cur_token = _cpp_temp_token (pfile);
   *plhs = _cpp_lex_direct (pfile);
-  valid = pfile->buffer->cur == pfile->buffer->rlimit;
-  _cpp_pop_buffer (pfile);
+  if (pfile->buffer->cur != pfile->buffer->rlimit)
+    {
+      _cpp_pop_buffer (pfile);
+      _cpp_backup_tokens (pfile, 1);
+      *lhsend = '\0';
 
-  return valid;
+      /* Mandatory error for all apart from assembler.  */
+      if (CPP_OPTION (pfile, lang) != CLK_ASM)
+       cpp_error (pfile, CPP_DL_ERROR,
+        "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
+                  buf, cpp_token_as_text (pfile, rhs));
+      return false;
+    }
+
+  _cpp_pop_buffer (pfile);
+  return true;
 }
 
 /* Handles an arbitrarily long sequence of ## operators, with initial
@@ -461,22 +501,12 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
        abort ();
 
       if (!paste_tokens (pfile, &lhs, rhs))
-       {
-         _cpp_backup_tokens (pfile, 1);
-
-         /* Mandatory error for all apart from assembler.  */
-         if (CPP_OPTION (pfile, lang) != CLK_ASM)
-           cpp_error (pfile, CPP_DL_ERROR,
-        "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
-                      cpp_token_as_text (pfile, lhs),
-                      cpp_token_as_text (pfile, rhs));
-         break;
-       }
+       break;
     }
   while (rhs->flags & PASTE_LEFT);
 
   /* Put the resulting token in its own context.  */
-  push_token_context (pfile, NULL, lhs, 1);
+  _cpp_push_token_context (pfile, NULL, lhs, 1);
 }
 
 /* Returns TRUE if the number of arguments ARGC supplied in an
@@ -690,7 +720,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
         too difficult.  We re-insert it in its own context.  */
       _cpp_backup_tokens (pfile, 1);
       if (padding)
-       push_token_context (pfile, NULL, padding, 1);
+       _cpp_push_token_context (pfile, NULL, padding, 1);
     }
 
   return NULL;
@@ -746,7 +776,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
       macro->used = 1;
 
       if (macro->paramc == 0)
-       push_token_context (pfile, node, macro->exp.tokens, macro->count);
+       _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count);
 
       return 1;
     }
@@ -939,8 +969,8 @@ push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
 }
 
 /* Push a list of tokens.  */
-static void
-push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
+void
+_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
                    const cpp_token *first, unsigned int count)
 {
   cpp_context *context = next_context (pfile);
@@ -1151,7 +1181,7 @@ cpp_scan_nooutput (cpp_reader *pfile)
   pfile->state.prevent_expansion--;
 }
 
-/* Step back one (or more) tokens.  Can only step mack more than 1 if
+/* Step back one (or more) tokens.  Can only step back more than 1 if
    they are from the lexer, and not from macro expansion.  */
 void
 _cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
index bf07c1babe668bba41b97782f6c2074291693fa6..d4c838e7d4abde3228943cf649d2286164897b13 100644 (file)
@@ -1,5 +1,5 @@
 /* Dependency generator for Makefile fragments.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2007 Free Software Foundation, Inc.
    Contributed by Zack Weinberg, Mar 2000
 
 This program is free software; you can redistribute it and/or modify it
@@ -142,7 +142,13 @@ apply_vpath (struct deps *d, const char *t)
 
   /* Remove leading ./ in any case.  */
   while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
-    t += 2;
+    {
+      t += 2;
+      /* If we removed a leading ./, then also remove any /s after the
+        first.  */
+      while (IS_DIR_SEPARATOR (t[0]))
+       ++t;
+    }
 
   return t;
 }
index ba9546c28a07693b99a7f5c934958aecfaecd77b..7e05ce2b79e4d4468e2919f1dce7c39184807be7 100644 (file)
@@ -35,10 +35,9 @@ extern int errno;
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
-
-/* Prototype these in case the system headers don't provide them. */
-extern char *getpwd ();
-extern char *getwd ();
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
 
 #include "libiberty.h"
 
@@ -47,6 +46,8 @@ extern char *getwd ();
    the few exceptions to the general rule here.  */
 
 #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
+/* Prototype in case the system headers doesn't provide it. */
+extern char *getwd ();
 #define getcwd(buf,len) getwd(buf)
 #endif
 
@@ -64,7 +65,7 @@ extern char *getwd ();
    yield 0 and set errno.  */
 
 char *
-getpwd ()
+getpwd (void)
 {
   static char *pwd;
   static int failure_errno;
@@ -83,7 +84,7 @@ getpwd ()
             && dotstat.st_dev == pwdstat.st_dev))
 
        /* The shortcut didn't work.  Try the slow, ``sure'' way.  */
-       for (s = GUESSPATHLEN;  ! getcwd (p = xmalloc (s), s);  s *= 2)
+       for (s = GUESSPATHLEN;  !getcwd (p = XNEWVEC (char, s), s);  s *= 2)
          {
            int e = errno;
            free (p);
@@ -120,12 +121,12 @@ getpwd ()
 #endif
 
 char *
-getpwd ()
+getpwd (void)
 {
   static char *pwd = 0;
 
   if (!pwd)
-    pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1
+    pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
 #ifdef VMS
                  , 0
 #endif
index a5671a0a768041bc12a4e62473ea12aa3afc7fc4..bf34a6d297ed09630aa6754c48df4ede92f4452a 100644 (file)
@@ -421,7 +421,28 @@ htab_empty (htab_t htab)
       if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
        (*htab->del_f) (entries[i]);
 
-  memset (entries, 0, size * sizeof (PTR));
+  /* Instead of clearing megabyte, downsize the table.  */
+  if (size > 1024*1024 / sizeof (PTR))
+    {
+      int nindex = higher_prime_index (1024 / sizeof (PTR));
+      int nsize = prime_tab[nindex].prime;
+
+      if (htab->free_f != NULL)
+       (*htab->free_f) (htab->entries);
+      else if (htab->free_with_arg_f != NULL)
+       (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries);
+      if (htab->alloc_with_arg_f != NULL)
+       htab->entries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize,
+                                                          sizeof (PTR *));
+      else
+       htab->entries = (PTR *) (*htab->alloc_f) (nsize, sizeof (PTR *));
+     htab->size = nsize;
+     htab->size_prime_index = nindex;
+    }
+  else
+    memset (entries, 0, size * sizeof (PTR));
+  htab->n_deleted = 0;
+  htab->n_elements = 0;
 }
 
 /* Similar to htab_find_slot, but without several unwanted side effects:
index 065972b031ab5ef16a0c5f81365a53ca6db2cb07..aa6bb11a10c51266fe272de1b988db9e1046ca80 100644 (file)
@@ -62,24 +62,39 @@ for (i = 1; i <= n_headers; i++)
 print "#include " quote "opts.h" quote
 print "#include " quote "intl.h" quote
 print ""
+print "#ifdef GCC_DRIVER"
+print "int target_flags;"
+print "#endif /* GCC_DRIVER */"
+print ""
 
 for (i = 0; i < n_opts; i++) {
        name = var_name(flags[i]);
        if (name == "")
                continue;
 
-       if (flag_set_p("VarExists", flags[i]))
-               continue;
-
-       init = opt_args("Init", flags[i])
-       if (init != "")
-               init = " = " init;
-       else if (name in var_seen)
-               continue;
+       if (flag_set_p("VarExists", flags[i])) {
+               # Need it for the gcc driver.
+               if (name in var_seen)
+                       continue;
+               init = ""
+               gcc_driver = 1
+       }
+       else {
+               init = opt_args("Init", flags[i])
+               if (init != "")
+                       init = " = " init;
+               else if (name in var_seen)
+                       continue;
+               gcc_driver = 0
+       }
 
+       if (gcc_driver == 1)
+               print "#ifdef GCC_DRIVER"
        print "/* Set by -" opts[i] "."
        print "   " help[i] "  */"
        print var_type(flags[i]) name init ";"
+       if (gcc_driver == 1)
+               print "#endif /* GCC_DRIVER */"
        print ""
 
        var_seen[name] = 1;
@@ -107,8 +122,21 @@ print "const unsigned int cl_options_count = N_OPTS;\n"
 
 print "const struct cl_option cl_options[] =\n{"
 
-for (i = 0; i < n_opts; i++)
+j = 0
+for (i = 0; i < n_opts; i++) {
        back_chain[i] = "N_OPTS";
+       indices[opts[i]] = j;
+       # Combine the flags of identical switches.  Switches
+       # appear many times if they are handled by many front
+       # ends, for example.
+       while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+               flags[i + 1] = flags[i] " " flags[i + 1];
+               i++;
+               back_chain[i] = "N_OPTS";
+               indices[opts[i]] = j;
+       }
+       j++;
+}
 
 for (i = 0; i < n_opts; i++) {
        # Combine the flags of identical switches.  Switches
@@ -147,8 +175,21 @@ for (i = 0; i < n_opts; i++) {
        else
                hlp = quote help[i] quote;
 
-       printf("  { %c-%s%c,\n    %s,\n    %s, %u,\n",
-              quote, opts[i], quote, hlp, back_chain[i], len)
+       neg = opt_args("Negative", flags[i]);
+       if (neg != "")
+               idx = indices[neg]
+       else {
+               if (flag_set_p("RejectNegative", flags[i]))
+                       idx = -1;
+               else {
+                       if (opts[i] ~ "^[Wfm]")
+                               idx = indices[opts[i]];
+                       else
+                               idx = -1;
+               }
+       }
+       printf("  { %c-%s%c,\n    %s,\n    %s, %u, %d,\n",
+              quote, opts[i], quote, hlp, back_chain[i], len, idx)
        condition = opt_args("Condition", flags[i])
        cl_flags = switch_flags(flags[i])
        if (condition != "")
index a6537a1c3489441f947f6641b43b1c465d705a2a..e7ffc1a646ebbc96ff69e52a3b19544f634285e5 100644 (file)
@@ -1,4 +1,4 @@
-#  Copyright (C) 2003,2004 Free Software Foundation, Inc.
+#  Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
 #  Contributed by Kelley Cook, June 2004.
 #  Original code from Neil Booth, May 2003.
 #
@@ -118,9 +118,18 @@ print ""
 
 for (i = 0; i < n_opts; i++) {
        opt = opt_args("InverseMask", flags[i])
-       if (opt ~ ",")
-               print "#define TARGET_" nth_arg(1, opt) \
-                     " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
+       if (opt ~ ",") {
+               vname = var_name(flags[i])
+               macro = "OPTION_"
+               mask = "OPTION_MASK_"
+               if (vname == "") {
+                       vname = "target_flags"
+                       macro = "TARGET_"
+                       mask = "MASK_"
+               }
+               print "#define " macro nth_arg(1, opt) \
+                     " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
+       }
 }
 print ""
 
diff --git a/support/cpp2/opts-common.c b/support/cpp2/opts-common.c
new file mode 100644 (file)
index 0000000..dcbbe2c
--- /dev/null
@@ -0,0 +1,236 @@
+/* Command line option handling.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the 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, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "opts.h"
+
+/* Perform a binary search to find which option the command-line INPUT
+   matches.  Returns its index in the option array, and N_OPTS
+   (cl_options_count) on failure.
+
+   This routine is quite subtle.  A normal binary search is not good
+   enough because some options can be suffixed with an argument, and
+   multiple sub-matches can occur, e.g. input of "-pedantic" matching
+   the initial substring of "-pedantic-errors".
+
+   A more complicated example is -gstabs.  It should match "-g" with
+   an argument of "stabs".  Suppose, however, that the number and list
+   of switches are such that the binary search tests "-gen-decls"
+   before having tested "-g".  This doesn't match, and as "-gen-decls"
+   is less than "-gstabs", it will become the lower bound of the
+   binary search range, and "-g" will never be seen.  To resolve this
+   issue, opts.sh makes "-gen-decls" point, via the back_chain member,
+   to "-g" so that failed searches that end between "-gen-decls" and
+   the lexicographically subsequent switch know to go back and see if
+   "-g" causes a match (which it does in this example).
+
+   This search is done in such a way that the longest match for the
+   front end in question wins.  If there is no match for the current
+   front end, the longest match for a different front end is returned
+   (or N_OPTS if none) and the caller emits an error message.  */
+size_t
+find_opt (const char *input, int lang_mask)
+{
+  size_t mn, mx, md, opt_len;
+  size_t match_wrong_lang;
+  int comp;
+
+  mn = 0;
+  mx = cl_options_count;
+
+  /* Find mn such this lexicographical inequality holds:
+     cl_options[mn] <= input < cl_options[mn + 1].  */
+  while (mx - mn > 1)
+    {
+      md = (mn + mx) / 2;
+      opt_len = cl_options[md].opt_len;
+      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
+
+      if (comp < 0)
+       mx = md;
+      else
+       mn = md;
+    }
+
+  /* This is the switch that is the best match but for a different
+     front end, or cl_options_count if there is no match at all.  */
+  match_wrong_lang = cl_options_count;
+
+  /* Backtrace the chain of possible matches, returning the longest
+     one, if any, that fits best.  With current GCC switches, this
+     loop executes at most twice.  */
+  do
+    {
+      const struct cl_option *opt = &cl_options[mn];
+
+      /* Is the input either an exact match or a prefix that takes a
+        joined argument?  */
+      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
+         && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
+       {
+         /* If language is OK, return it.  */
+         if (opt->flags & lang_mask)
+           return mn;
+
+         /* If we haven't remembered a prior match, remember this
+            one.  Any prior match is necessarily better.  */
+         if (match_wrong_lang == cl_options_count)
+           match_wrong_lang = mn;
+       }
+
+      /* Try the next possibility.  This is cl_options_count if there
+        are no more.  */
+      mn = opt->back_chain;
+    }
+  while (mn != cl_options_count);
+
+  /* Return the best wrong match, or cl_options_count if none.  */
+  return match_wrong_lang;
+}
+
+/* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
+   next one is the same as ORIG_NEXT_OPT_IDX.  */
+
+static bool
+cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
+{
+  /* An option can be canceled by the same option or an option with
+     Negative.  */
+  if (cl_options [next_opt_idx].neg_index == opt_idx)
+    return true;
+
+  if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
+    return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
+                         orig_next_opt_idx);
+    
+  return false;
+}
+
+/* Filter out options canceled by the ones after them.  */
+
+void
+prune_options (int *argcp, char ***argvp)
+{
+  int argc = *argcp;
+  int *options = xmalloc (argc * sizeof (*options));
+  char **argv = xmalloc (argc * sizeof (char *));
+  int i, arg_count, need_prune = 0;
+  const struct cl_option *option;
+  size_t opt_index;
+
+  /* Scan all arguments.  */
+  for (i = 1; i < argc; i++)
+    {
+      int value = 1;
+      const char *opt = (*argvp) [i];
+
+      opt_index = find_opt (opt + 1, -1);
+      if (opt_index == cl_options_count
+         && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
+         && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+       {
+         char *dup;
+
+         /* Drop the "no-" from negative switches.  */
+         size_t len = strlen (opt) - 3;
+
+         dup = XNEWVEC (char, len + 1);
+         dup[0] = '-';
+         dup[1] = opt[1];
+         memcpy (dup + 2, opt + 5, len - 2 + 1);
+         opt = dup;
+         value = 0;
+         opt_index = find_opt (opt + 1, -1);
+         free (dup);
+       }
+
+      if (opt_index == cl_options_count)
+       {
+cont:
+         options [i] = 0;
+         continue;
+       }
+
+      option = &cl_options[opt_index];
+      if (option->neg_index < 0)
+       goto cont;
+
+      /* Skip joined switches.  */
+      if ((option->flags & CL_JOINED))
+       goto cont;
+
+      /* Reject negative form of switches that don't take negatives as
+        unrecognized.  */
+      if (!value && (option->flags & CL_REJECT_NEGATIVE))
+       goto cont;
+
+      options [i] = (int) opt_index;
+      need_prune |= options [i];
+    }
+
+  if (!need_prune)
+    goto done;
+
+  /* Remove arguments which are negated by others after them.  */
+  argv [0] = (*argvp) [0];
+  arg_count = 1;
+  for (i = 1; i < argc; i++)
+    {
+      int j, opt_idx;
+
+      opt_idx = options [i];
+      if (opt_idx)
+       {
+         int next_opt_idx;
+         for (j = i + 1; j < argc; j++)
+           {
+             next_opt_idx = options [j];
+             if (next_opt_idx
+                 && cancel_option (opt_idx, next_opt_idx,
+                                   next_opt_idx))
+               break;
+           }
+       }
+      else
+       goto keep;
+
+      if (j == argc)
+       {
+keep:
+         argv [arg_count] = (*argvp) [i];
+         arg_count++;
+       }
+    }
+
+  if (arg_count != argc)
+    {
+      *argcp = arg_count;
+      *argvp = argv;
+    }
+  else
+    {
+done:
+      free (argv);
+    }
+
+  free (options);
+}
index 3d11d851664f194fe5f6c0ec18416aa213f250c0..178c5587f0372427c629a34f71e29510c7078a64 100644 (file)
@@ -1,5 +1,6 @@
 /* Command line option handling.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -16,8 +17,8 @@ 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.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -44,7 +45,6 @@ static const char undocumented_msg[] = N_("This switch lacks documentation");
 const char **in_fnames;
 unsigned num_in_fnames;
 
-static size_t find_opt (const char *, int);
 static int common_handle_option (size_t scode, const char *arg, int value);
 static unsigned int handle_option (const char **argv, unsigned int lang_mask);
 static char *write_langs (unsigned int lang_mask);
@@ -53,93 +53,9 @@ static void complain_wrong_lang (const char *, const struct cl_option *,
 static void handle_options (unsigned int, const char **, unsigned int);
 static void wrap_help (const char *help, const char *item, unsigned int);
 static void print_help (void);
-static void print_filtered_help (unsigned int flag);
+static void print_filtered_help (unsigned int);
 static unsigned int print_switch (const char *text, unsigned int indent);
 
-/* Perform a binary search to find which option the command-line INPUT
-   matches.  Returns its index in the option array, and N_OPTS
-   (cl_options_count) on failure.
-
-   This routine is quite subtle.  A normal binary search is not good
-   enough because some options can be suffixed with an argument, and
-   multiple sub-matches can occur, e.g. input of "-pedantic" matching
-   the initial substring of "-pedantic-errors".
-
-   A more complicated example is -gstabs.  It should match "-g" with
-   an argument of "stabs".  Suppose, however, that the number and list
-   of switches are such that the binary search tests "-gen-decls"
-   before having tested "-g".  This doesn't match, and as "-gen-decls"
-   is less than "-gstabs", it will become the lower bound of the
-   binary search range, and "-g" will never be seen.  To resolve this
-   issue, opts.sh makes "-gen-decls" point, via the back_chain member,
-   to "-g" so that failed searches that end between "-gen-decls" and
-   the lexicographically subsequent switch know to go back and see if
-   "-g" causes a match (which it does in this example).
-
-   This search is done in such a way that the longest match for the
-   front end in question wins.  If there is no match for the current
-   front end, the longest match for a different front end is returned
-   (or N_OPTS if none) and the caller emits an error message.  */
-static size_t
-find_opt (const char *input, int lang_mask)
-{
-  size_t mn, mx, md, opt_len;
-  size_t match_wrong_lang;
-  int comp;
-
-  mn = 0;
-  mx = cl_options_count;
-
-  /* Find mn such this lexicographical inequality holds:
-     cl_options[mn] <= input < cl_options[mn + 1].  */
-  while (mx - mn > 1)
-    {
-      md = (mn + mx) / 2;
-      opt_len = cl_options[md].opt_len;
-      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
-
-      if (comp < 0)
-       mx = md;
-      else
-       mn = md;
-    }
-
-  /* This is the switch that is the best match but for a different
-     front end, or cl_options_count if there is no match at all.  */
-  match_wrong_lang = cl_options_count;
-
-  /* Backtrace the chain of possible matches, returning the longest
-     one, if any, that fits best.  With current GCC switches, this
-     loop executes at most twice.  */
-  do
-    {
-      const struct cl_option *opt = &cl_options[mn];
-
-      /* Is the input either an exact match or a prefix that takes a
-        joined argument?  */
-      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
-         && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
-       {
-         /* If language is OK, return it.  */
-         if (opt->flags & lang_mask)
-
-
-         /* If we haven't remembered a prior match, remember this
-            one.  Any prior match is necessarily better.  */
-         if (match_wrong_lang == cl_options_count)
-           match_wrong_lang = mn;
-       }
-
-      /* Try the next possibility.  This is cl_options_count if there
-        are no more.  */
-      mn = opt->back_chain;
-    }
-  while (mn != cl_options_count);
-
-  /* Return the best wrong match, or cl_options_count if none.  */
-  return match_wrong_lang;
-}
-
 /* If ARG is a non-negative integer made up solely of digits, return its
    value, otherwise return -1.  */
 static int
@@ -168,7 +84,7 @@ write_langs (unsigned int mask)
     if (mask & (1U << n))
       len += strlen (lang_name) + 1;
 
-  result = xmalloc (len);
+  result = XNEWVEC (char, len);
   len = 0;
   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
     if (mask & (1U << n))
@@ -224,7 +140,7 @@ handle_option (const char **argv, unsigned int lang_mask)
       /* Drop the "no-" from negative switches.  */
       size_t len = strlen (opt) - 3;
 
-      dup = xmalloc (len + 1);
+      dup = XNEWVEC (char, len + 1);
       dup[0] = '-';
       dup[1] = opt[1];
       memcpy (dup + 2, opt + 5, len - 2 + 1);
@@ -338,7 +254,7 @@ handle_option (const char **argv, unsigned int lang_mask)
       }
 
   if (option->flags & lang_mask)
-    if ((*lang_hooks.handle_option) (opt_index, arg, value) == 0)
+    if (lang_hooks.handle_option (opt_index, arg, value) == 0)
       result = 0;
 
   if (result && (option->flags & CL_COMMON))
@@ -356,7 +272,7 @@ handle_option (const char **argv, unsigned int lang_mask)
 }
 
 /* Handle FILENAME from the command line.  */
-void
+static void
 add_input_filename (const char *filename)
 {
   num_in_fnames++;
index 2c2340c3bdd18c0062f01fa6784eb2a7f8adf1ea..3af501fbf999b06d10cda4202f49df0a02c77ee6 100644 (file)
@@ -46,6 +46,7 @@ struct cl_option
   const char *help;
   unsigned short back_chain;
   unsigned char opt_len;
+  int neg_index;
   unsigned int flags;
   void *flag_var;
   enum cl_var_type var_type;
@@ -63,6 +64,7 @@ struct cl_option_state {
 extern const struct cl_option cl_options[];
 extern const unsigned int cl_options_count;
 extern const char *const lang_names[];
+extern bool no_unit_at_a_time_default;
 
 #define CL_DISABLED            (1 << 21) /* Disabled in this configuration.  */
 #define CL_TARGET              (1 << 22) /* Target-specific option.  */
@@ -83,6 +85,8 @@ extern const char **in_fnames;
 
 extern unsigned num_in_fnames;
 
+size_t find_opt (const char *input, int lang_mask);
+extern void prune_options (int *argcp, char ***argvp);
 extern void decode_options (unsigned int argc, const char **argv);
 extern int option_enabled (int opt_idx);
 extern bool get_option_state (int, struct cl_option_state *);
index 3cb091fcf931a0099f186deb67556a85dfc6ff82..fda098bc3e61f155b6f43c1ce24be82e4c814e57 100644 (file)
@@ -23,9 +23,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #ifndef GCC_OUTPUT_H
 #define GCC_OUTPUT_H
 
-/* Compute branch alignments based on frequency information in the CFG.  */
-extern void compute_alignments (void);
-
 /* Initialize data in final at the beginning of a compilation.  */
 extern void init_final (const char *);
 
@@ -153,77 +150,6 @@ extern int regno_clobbered_at_setjmp (int);
 
 /* Functions in varasm.c.  */
 
-/* Tell assembler to switch to text section.  */
-extern void text_section (void);
-
-/* Tell assembler to switch to unlikely-to-be-executed text section.  */
-extern void unlikely_text_section (void);
-
-/* Tell assembler to switch to data section.  */
-extern void data_section (void);
-
-/* Tell assembler to switch to read-only data section.  This is normally
-   the text section.  */
-extern void readonly_data_section (void);
-
-/* Determine if we're in the text section.  */
-extern int in_text_section (void);
-
-/* Determine if we're in the unlikely-to-be-executed text section.  */
-extern int in_unlikely_text_section (void);
-
-#ifdef CTORS_SECTION_ASM_OP
-extern void ctors_section (void);
-#endif
-
-#ifdef DTORS_SECTION_ASM_OP
-extern void dtors_section (void);
-#endif
-
-#ifdef BSS_SECTION_ASM_OP
-extern void bss_section (void);
-#endif
-
-#ifdef INIT_SECTION_ASM_OP
-extern void init_section (void);
-#endif
-
-#ifdef FINI_SECTION_ASM_OP
-extern void fini_section (void);
-#endif
-
-#ifdef EXPORTS_SECTION_ASM_OP
-extern void exports_section (void);
-#endif
-
-#ifdef DRECTVE_SECTION_ASM_OP
-extern void drectve_section (void);
-#endif
-
-#ifdef SDATA_SECTION_ASM_OP
-extern void sdata_section (void);
-#endif
-
-/* Tell assembler to change to section NAME for DECL.
-   If DECL is NULL, just switch to section NAME.
-   If NAME is NULL, get the name from DECL.
-   If RELOC is 1, the initializer for DECL contains relocs.  */
-extern void named_section (tree, const char *, int);
-
-/* Tell assembler to switch to the section for function DECL.  */
-extern void function_section (tree);
-
-/* Tell assembler to switch to the most recently used text section.  */
-extern void current_function_section (tree);
-
-/* Tell assembler to switch to the section for string merging.  */
-extern void mergeable_string_section (tree, unsigned HOST_WIDE_INT,
-                                     unsigned int);
-
-/* Tell assembler to switch to the section for constant merging.  */
-extern void mergeable_constant_section (enum machine_mode,
-                                       unsigned HOST_WIDE_INT, unsigned int);
-
 /* Declare DECL to be a weak symbol.  */
 extern void declare_weak (tree);
 /* Merge weak status.  */
@@ -241,10 +167,6 @@ extern void weak_finish (void);
    Prefixes such as % are optional.  */
 extern int decode_reg_name (const char *);
 
-/* Make the rtl for variable VAR be volatile.
-   Use this only for static variables.  */
-extern void make_var_volatile (tree);
-
 extern void assemble_alias (tree, tree);
 
 extern void default_assemble_visibility (tree, int);
@@ -274,6 +196,10 @@ extern void assemble_end_function (tree, const char *);
    initial value (that will be done by the caller).  */
 extern void assemble_variable (tree, int, int, int);
 
+/* Compute the alignment of variable specified by DECL.
+   DONT_OUTPUT_DATA is from assemble_variable.  */
+extern void align_variable (tree decl, bool dont_output_data);
+
 /* Output something to declare an external symbol to the assembler.
    (Most assemblers don't need this, so we normally output nothing.)
    Do nothing if DECL is not external.  */
@@ -346,8 +272,16 @@ extern int get_pool_size (void);
 extern rtx peephole (rtx);
 #endif
 
-/* Write all the constants in the constant pool.  */
-extern void output_constant_pool (const char *, tree);
+extern void output_shared_constant_pool (void);
+
+extern void output_object_blocks (void);
+
+/* Whether a constructor CTOR is a valid static constant initializer if all
+   its elements are.  This used to be internal to initializer_constant_valid_p
+   and has been exposed to let other functions like categorize_ctor_elements
+   evaluate the property while walking a constructor for other purposes.  */
+
+extern bool constructor_static_from_elts_p (tree);
 
 /* Return nonzero if VALUE is a valid constant-valued expression
    for use in initializing a static variable; one that can be an
@@ -438,33 +372,11 @@ extern rtx this_is_asm_operands;
 extern int size_directive_output;
 extern tree last_assemble_variable_decl;
 
-enum in_section { no_section, in_text, in_unlikely_executed_text, in_data,
-                 in_named
-#ifdef BSS_SECTION_ASM_OP
-  , in_bss
-#endif
-#ifdef CTORS_SECTION_ASM_OP
-  , in_ctors
-#endif
-#ifdef DTORS_SECTION_ASM_OP
-  , in_dtors
-#endif
-#ifdef READONLY_DATA_SECTION_ASM_OP
-  , in_readonly_data
-#endif
-#ifdef EXTRA_SECTIONS
-  , EXTRA_SECTIONS
-#endif
-};
-
-extern const char *last_text_section_name;
-extern enum in_section last_text_section;
 extern bool first_function_block_is_cold;
 
 /* Decide whether DECL needs to be in a writable section.
    RELOC is the same as for SELECT_SECTION.  */
 extern bool decl_readonly_section (tree, int);
-extern bool decl_readonly_section_1 (tree, int, int);
 
 /* This can be used to compute RELOC for the function above, when
    given a constant expression.  */
@@ -476,14 +388,6 @@ extern const char *user_label_prefix;
 /* Default target function prologue and epilogue assembler output.  */
 extern void default_function_pro_epilogue (FILE *, HOST_WIDE_INT);
 
-/* Tell assembler to switch to the section for the exception table.  */
-extern void default_exception_section (void);
-
-/* Tell assembler to switch to the section for the EH frames.  */
-extern void named_section_eh_frame_section (void);
-extern void collect2_eh_frame_section (void);
-extern void default_eh_frame_section (void);
-
 /* Default target hook that outputs nothing to a stream.  */
 extern void no_asm_to_stream (FILE *);
 
@@ -502,7 +406,23 @@ extern void no_asm_to_stream (FILE *);
 #define SECTION_OVERRIDE 0x20000       /* allow override of default flags */
 #define SECTION_TLS     0x40000        /* contains thread-local storage */
 #define SECTION_NOTYPE  0x80000        /* don't output @progbits */
-#define SECTION_MACH_DEP 0x100000      /* subsequent bits reserved for target */
+#define SECTION_DECLARED 0x100000      /* section has been used */
+#define SECTION_STYLE_MASK 0x600000    /* bits used for SECTION_STYLE */
+#define SECTION_COMMON   0x800000      /* contains common data */
+#define SECTION_MACH_DEP 0x1000000     /* subsequent bits reserved for target */
+
+/* This SECTION_STYLE is used for unnamed sections that we can switch
+   to using a special assembler directive.  */
+#define SECTION_UNNAMED         0x000000
+
+/* This SECTION_STYLE is used for named sections that we can switch
+   to using a general section directive.  */
+#define SECTION_NAMED   0x200000
+
+/* This SECTION_STYLE is used for sections that we cannot switch to at
+   all.  The choice of section is implied by the directive that we use
+   to declare the object.  */
+#define SECTION_NOSWITCH 0x400000
 
 /* A helper function for default_elf_select_section and
    default_elf_unique_section.  Categorizes the DECL.  */
@@ -541,18 +461,119 @@ enum section_category
   SECCAT_TBSS
 };
 
+/* Information that is provided by all instances of the section type.  */
+struct section_common GTY(()) {
+  /* The set of SECTION_* flags that apply to this section.  */
+  unsigned int flags;
+};
+
+/* Information about a SECTION_NAMED section.  */
+struct named_section GTY(()) {
+  struct section_common common;
+
+  /* The name of the section.  */
+  const char *name;
+
+  /* If nonnull, the VAR_DECL or FUNCTION_DECL with which the
+     section is associated.  */
+  tree decl;
+};
+
+/* A callback that writes the assembly code for switching to an unnamed
+   section.  The argument provides callback-specific data.  */
+typedef void (*unnamed_section_callback) (const void *);
+
+/* Information about a SECTION_UNNAMED section.  */
+struct unnamed_section GTY(()) {
+  struct section_common common;
+
+  /* The callback used to switch to the section, and the data that
+     should be passed to the callback.  */
+  unnamed_section_callback GTY ((skip)) callback;
+  const void *GTY ((skip)) data;
+
+  /* The next entry in the chain of unnamed sections.  */
+  section *next;
+};
+
+/* A callback that writes the assembly code for a decl in a
+   SECTION_NOSWITCH section.  DECL is the decl that should be assembled
+   and NAME is the name of its SYMBOL_REF.  SIZE is the size of the decl
+   in bytes and ROUNDED is that size rounded up to the next
+   BIGGEST_ALIGNMENT / BITS_PER_UNIT boundary.
+
+   Return true if the callback used DECL_ALIGN to set the object's
+   alignment.  A false return value implies that we are relying
+   on the rounded size to align the decl.  */
+typedef bool (*noswitch_section_callback) (tree decl, const char *name,
+                                          unsigned HOST_WIDE_INT size,
+                                          unsigned HOST_WIDE_INT rounded);
+
+/* Information about a SECTION_NOSWITCH section.  */
+struct noswitch_section GTY(()) {
+  struct section_common common;
+
+  /* The callback used to assemble decls in this section.  */
+  noswitch_section_callback GTY ((skip)) callback;
+};
+
+/* Information about a section, which may be named or unnamed.  */
+union section GTY ((desc ("SECTION_STYLE (&(%h))")))
+{
+  struct section_common GTY ((skip)) common;
+  struct named_section GTY ((tag ("SECTION_NAMED"))) named;
+  struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed;
+  struct noswitch_section GTY ((tag ("SECTION_NOSWITCH"))) noswitch;
+};
+
+/* Return the style of section SECT.  */
+#define SECTION_STYLE(SECT) ((SECT)->common.flags & SECTION_STYLE_MASK)
+
+struct object_block;
+
+/* Special well-known sections.  */
+extern GTY(()) section *text_section;
+extern GTY(()) section *data_section;
+extern GTY(()) section *readonly_data_section;
+extern GTY(()) section *sdata_section;
+extern GTY(()) section *ctors_section;
+extern GTY(()) section *dtors_section;
+extern GTY(()) section *bss_section;
+extern GTY(()) section *sbss_section;
+extern GTY(()) section *exception_section;
+extern GTY(()) section *eh_frame_section;
+extern GTY(()) section *tls_comm_section;
+extern GTY(()) section *comm_section;
+extern GTY(()) section *lcomm_section;
+extern GTY(()) section *bss_noswitch_section;
+
+extern GTY(()) section *in_section;
+extern GTY(()) bool in_cold_section_p;
+
+extern section *get_unnamed_section (unsigned int, void (*) (const void *),
+                                    const void *);
+extern section *get_section (const char *, unsigned int, tree);
+extern section *get_named_section (tree, const char *, int);
+extern void place_block_symbol (rtx);
+extern rtx get_section_anchor (struct object_block *, HOST_WIDE_INT,
+                              enum tls_model);
+extern section *mergeable_constant_section (enum machine_mode,
+                                           unsigned HOST_WIDE_INT,
+                                           unsigned int);
+extern section *function_section (tree);
+extern section *unlikely_text_section (void);
+extern section *current_function_section (void);
+
+extern bool unlikely_text_section_p (section *);
+extern void switch_to_section (section *);
+extern void output_section_asm_op (const void *);
 
-extern bool set_named_section_flags (const char *, unsigned int);
-#define named_section_flags(NAME, FLAGS) \
-  named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE)
-extern void named_section_real (const char *, unsigned int, tree);
-extern bool named_section_first_declaration (const char *);
 extern unsigned int default_section_type_flags (tree, const char *, int);
-extern unsigned int default_section_type_flags_1 (tree, const char *, int, int);
 
+extern bool have_global_bss_p (void);
 extern void default_no_named_section (const char *, unsigned int, tree);
 extern void default_elf_asm_named_section (const char *, unsigned int, tree);
-extern enum section_category categorize_decl_for_section (tree, int, int);
+extern enum section_category categorize_decl_for_section (tree, int);
 extern void default_coff_asm_named_section (const char *, unsigned int, tree);
 extern void default_pe_asm_named_section (const char *, unsigned int, tree);
 
@@ -563,24 +584,24 @@ extern void default_stabs_asm_out_constructor (rtx, int);
 extern void default_named_section_asm_out_constructor (rtx, int);
 extern void default_ctor_section_asm_out_constructor (rtx, int);
 
-extern void default_select_section (tree, int, unsigned HOST_WIDE_INT);
-extern void default_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
-extern void default_elf_select_section_1 (tree, int,
-                                         unsigned HOST_WIDE_INT, int);
+extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT);
+extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
 extern void default_unique_section (tree, int);
-extern void default_unique_section_1 (tree, int, int);
-extern void default_function_rodata_section (tree);
-extern void default_no_function_rodata_section (tree);
-extern void default_select_rtx_section (enum machine_mode, rtx,
-                                       unsigned HOST_WIDE_INT);
-extern void default_elf_select_rtx_section (enum machine_mode, rtx,
+extern section *default_function_rodata_section (tree);
+extern section *default_no_function_rodata_section (tree);
+extern section *default_select_rtx_section (enum machine_mode, rtx,
                                            unsigned HOST_WIDE_INT);
+extern section *default_elf_select_rtx_section (enum machine_mode, rtx,
+                                               unsigned HOST_WIDE_INT);
 extern void default_encode_section_info (tree, rtx, int);
 extern const char *default_strip_name_encoding (const char *);
+extern void default_asm_output_anchor (rtx);
+extern bool default_use_anchors_for_symbol_p (rtx);
 extern bool default_binds_local_p (tree);
 extern bool default_binds_local_p_1 (tree, int);
 extern void default_globalize_label (FILE *, const char *);
 extern void default_emit_unwind_label (FILE *, tree, int, int);
+extern void default_emit_except_table_label (FILE *);
 extern void default_internal_label (FILE *, const char *, unsigned long);
 extern void default_file_start (void);
 extern void file_end_indicate_exec_stack (void);
index a559bcd3a39a3942b9d1e1e22c1ab99ba84093d5..652f49b9398054b6eeef8243d0faf400e6ee5e21 100644 (file)
@@ -113,7 +113,7 @@ get_key_value (char *key)
 static char *
 save_string (const char *s, int len)
 {
-  char *result = xmalloc (len + 1);
+  char *result = XNEWVEC (char, len + 1);
 
   memcpy (result, s, len);
   result[len] = 0;
@@ -199,7 +199,7 @@ translate_name (char *name)
           keylen++)
        ;
 
-      key = alloca (keylen + 1);
+      key = (char *) alloca (keylen + 1);
       strncpy (key, &name[1], keylen);
       key[keylen] = 0;
 
index e4eea8c8a662dfe4404533b2bae4132bcfa306ec..3f863f4707293df9adbcfc64c1c8544267de8efd 100644 (file)
@@ -61,6 +61,9 @@ static const char *deps_file;
 /* The prefix given by -iprefix, if any.  */
 static const char *iprefix;
 
+/* The multilib directory given by -imultilib, if any.  */
+static const char *imultilib;
+
 /* The system root, if any.  Overridden by -isysroot.  */
 static const char *sysroot = TARGET_SYSTEM_ROOT;
 
@@ -416,6 +419,10 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value)
       iprefix = arg;
       break;
 
+    case OPT_imultilib:
+      imultilib = arg;
+      break;
+
     case OPT_iquote:
       add_path (xstrdup (arg), QUOTE, 0, true);
       break;
@@ -544,7 +551,7 @@ sdcpp_common_post_options (const char **pfilename)
 
   sanitize_cpp_opts ();
 
-  register_include_chains (parse_in, sysroot, iprefix,
+  register_include_chains (parse_in, sysroot, iprefix, imultilib,
                           std_inc, 0, verbose);
 
   /* Open the output now.  We must do so even if flag_no_output is
index 87fd871877f0d8c4eaf97b3ec58e2fb1bcdca43b..f203f500fad0fce4f2f5a3a88fece1d3229a09d5 100644 (file)
@@ -241,6 +241,10 @@ SOURCE=.\options.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=".\opts-common.c"\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\opts.c\r
 # End Source File\r
 # Begin Source File\r
@@ -316,6 +320,14 @@ SOURCE=.\win32\dirent.h
 # PROP Default_Filter "h;hpp;hxx;hm;inl"\r
 # Begin Source File\r
 \r
+SOURCE=.\libiberty\filenames.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\libiberty\hashtab.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\libiberty\obstack.h\r
 # End Source File\r
 # End Group\r
@@ -353,6 +365,10 @@ SOURCE=.\libiberty.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\md5.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\options.h\r
 # End Source File\r
 # Begin Source File\r
index b4d655ad785e02be3f94868e8766059376cfa510..58f62742d0e795355b5ed79e0170dbc7c08a5af3 100644 (file)
@@ -222,6 +222,10 @@ imacros
 SDCPP Joined Separate
 -imacros <file>        Accept definition of macros in <file>
 
+imultilib
+C ObjC C++ ObjC++ Joined Separate
+-imultilib <dir> Set <dir> to be the multilib include subdirectory
+
 include
 SDCPP Joined Separate
 -include <file>        Include the contents of <file> before other files
index 6d192ac615ca274ff395665ff90c887ba4082e8e..8f669437ed1178ef1dab8f44a9ce3cf0ef2eb5a0 100644 (file)
@@ -231,6 +231,8 @@ extern int errno;
 # endif
 #endif
 
+#define ICE_EXIT_CODE 4
+
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
@@ -619,6 +621,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 # define FALSE false
 #endif /* !__cplusplus */
 
+/////* Get definition of double_int.  */
+////#include "double-int.h"
 
 /* Some compilers do not allow the use of unsigned char in bitfields.  */
 #define BOOL_BITFIELD unsigned int
@@ -738,7 +742,11 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
         TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT          \
         LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE               \
        TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC         \
-       PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF
+       PREDICATE_CODES SPECIAL_MODE_PREDICATES HOST_PTR_PRINTF            \
+       EXTRA_SECTIONS EXTRA_SECTION_FUNCTIONS READONLY_DATA_SECTION       \
+       TARGET_ASM_EXCEPTION_SECTION TARGET_ASM_EH_FRAME_SECTION           \
+       SMALL_ARG_MAX ASM_OUTPUT_SHARED_BSS ASM_OUTPUT_SHARED_COMMON       \
+       ASM_OUTPUT_SHARED_LOCAL UNALIGNED_WORD_ASM_OP
 
 /* Hooks that are no longer used.  */
  #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE  \
index 222bbb0c1ecca4f1e584efe193457dcfa46a447c..310c138e308ee47a383f2e189204ba5f73449f08 100644 (file)
@@ -1,11 +1,17 @@
 #include "version.h"
 
-/* This is the string reported as the version number by all components
-   of the compiler.  If you distribute a modified version of GCC,
-   please modify this string to indicate that, e.g. by putting your
-   organization's name in parentheses at the end of the string.  */
+/* This is the trailing component of the string reported as the
+   version number by all components of the compiler.  For an official
+   FSF release, it is empty.  If you distribute a modified version of
+   GCC, please change this string to indicate that.  The suggested
+   format is a leading space, followed by your organization's name
+   in parentheses.  You may also wish to include a number indicating
+   the revision of your modified compiler.  */
 
-const char version_string[] = "4.1.2 + SDCC";
+#define BASEVER "4.2.0"
+#define DATESTAMP
+#define DEVPHASE
+#define VERSUFFIX " + SDCC"
 
 /* This is the location of the online document giving instructions for
    reporting bugs.  If you distribute a modified version of GCC,
@@ -15,3 +21,8 @@ const char version_string[] = "4.1.2 + SDCC";
    not bugs in your modifications.)  */
 
 const char bug_report_url[] = "<URL:http://sdcc.sourceforge.net>";
+
+/* The complete version string, assembled from several pieces.
+   BASEVER, DATESTAMP, and DEVPHASE are defined by the Makefile.  */
+
+const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX;