OSDN Git Service

* tree-inline.c (find_builtin_longjmp_call): Save and restore
[pf3gnuchains/gcc-fork.git] / gcc / cpplib.c
index 59e2fe6..ed2bc95 100644 (file)
@@ -21,6 +21,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #include "cpplib.h"
 #include "cpphash.h"
@@ -119,6 +121,11 @@ static struct pragma_entry *lookup_pragma_entry
 static struct pragma_entry *insert_pragma_entry
   PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *,
           pragma_cb));
+static int count_registered_pragmas    PARAMS ((struct pragma_entry *));
+static char ** save_registered_pragmas 
+  PARAMS ((struct pragma_entry *, char **));
+static char ** restore_registered_pragmas 
+  PARAMS ((cpp_reader *, struct pragma_entry *, char **));
 static void do_pragma_once     PARAMS ((cpp_reader *));
 static void do_pragma_poison   PARAMS ((cpp_reader *));
 static void do_pragma_system_header    PARAMS ((cpp_reader *));
@@ -162,14 +169,7 @@ D(ident,   T_IDENT,        EXTENSION, IN_I)           /*     11 */ \
 D(import,      T_IMPORT,       EXTENSION, INCL | EXPAND)  /* 0 ObjC */ \
 D(assert,      T_ASSERT,       EXTENSION, 0)              /* 0 SVR4 */ \
 D(unassert,    T_UNASSERT,     EXTENSION, 0)              /* 0 SVR4 */ \
-SCCS_ENTRY                                                /* 0 SVR4? */
-
-/* #sccs is not always recognized.  */
-#ifdef SCCS_DIRECTIVE
-# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION, 0)
-#else
-# define SCCS_ENTRY /* nothing */
-#endif
+D(sccs,                T_SCCS,         EXTENSION, 0)              /* 0 SVR4? */
 
 /* Use the table to generate a series of prototypes, an enum for the
    directive names, and an array of directive handlers.  */
@@ -214,7 +214,7 @@ skip_rest_of_line (pfile)
      cpp_reader *pfile;
 {
   /* Discard all stacked contexts.  */
-  while (pfile->context != &pfile->base_context)
+  while (pfile->context->prev)
     _cpp_pop_context (pfile);
 
   /* Sweep up all tokens remaining on the line.  */
@@ -284,9 +284,7 @@ static void
 prepare_directive_trad (pfile)
      cpp_reader *pfile;
 {
-  if (pfile->directive == &dtable[T_DEFINE])
-    CUR (pfile->context) = pfile->buffer->cur;
-  else
+  if (pfile->directive != &dtable[T_DEFINE])
     {
       bool no_expand = (pfile->directive
                        && ! (pfile->directive->flags & EXPAND));
@@ -305,14 +303,11 @@ prepare_directive_trad (pfile)
                           pfile->out.cur - pfile->out.base);
     }
 
-  /* Report diagnostics on the line of the directive.  */
-  pfile->line = pfile->directive_line;
-
   /* Stop ISO C from expanding anything.  */
   pfile->state.prevent_expansion++;
 }
 
-/* Output diagnostics for a directive DIR.  INDENTED is non-zero if
+/* Output diagnostics for a directive DIR.  INDENTED is nonzero if
    the '#' was indented.  */
 static void
 directive_diagnostics (pfile, dir, indented)
@@ -348,10 +343,10 @@ directive_diagnostics (pfile, dir, indented)
     }
 }
 
-/* Check if we have a known directive.  INDENTED is non-zero if the
+/* Check if we have a known directive.  INDENTED is nonzero if the
    '#' of the directive was indented.  This function is in this file
    to save unnecessarily exporting dtable etc. to cpplex.c.  Returns
-   non-zero if the line of tokens has been handled, zero if we should
+   nonzero if the line of tokens has been handled, zero if we should
    continue processing the line.  */
 int
 _cpp_handle_directive (pfile, indented)
@@ -376,10 +371,10 @@ _cpp_handle_directive (pfile, indented)
 
   if (dname->type == CPP_NAME)
     {
-      if (dname->val.node->directive_index)
-       dir = &dtable[dname->val.node->directive_index - 1];
+      if (dname->val.node->is_directive)
+       dir = &dtable[dname->val.node->directive_index];
     }
-  /* We do not recognise the # followed by a number extension in
+  /* We do not recognize the # followed by a number extension in
      assembler code.  */
   else if (dname->type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
     {
@@ -390,10 +385,6 @@ _cpp_handle_directive (pfile, indented)
                   "style of line directive is a GCC extension");
     }
 
-  pfile->directive = dir;
-  if (CPP_OPTION (pfile, traditional))
-    prepare_directive_trad (pfile);
-
   if (dir)
     {
       /* If we have a directive that is not an opening conditional,
@@ -423,6 +414,7 @@ _cpp_handle_directive (pfile, indented)
             skipping or not, we should lex angle-bracketed headers
             correctly, and maybe output some diagnostics.  */
          pfile->state.angled_headers = dir->flags & INCL;
+         pfile->state.directive_wants_padding = dir->flags & INCL;
          if (! CPP_OPTION (pfile, preprocessed))
            directive_diagnostics (pfile, dir, indented);
          if (pfile->state.skipping && !(dir->flags & COND))
@@ -444,17 +436,12 @@ _cpp_handle_directive (pfile, indented)
                   cpp_token_as_text (pfile, dname));
     }
 
+  pfile->directive = dir;
+  if (CPP_OPTION (pfile, traditional))
+    prepare_directive_trad (pfile);
+
   if (dir)
-    {
-      /* If we are processing a `#define' directive and we have been
-        requested to expand comments into macros, then re-enable
-        saving of comments.  */
-      if (dir == &dtable[T_DEFINE])
-       pfile->state.save_comments =
-         ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
-
-      (*pfile->directive->handler) (pfile);
-    }
+    (*pfile->directive->handler) (pfile);
   else if (skip == 0)
     _cpp_backup_tokens (pfile, 1);
 
@@ -480,6 +467,9 @@ run_directive (pfile, dir_no, buf, count)
 {
   cpp_push_buffer (pfile, (const uchar *) buf, count,
                   /* from_stage3 */ true, 1);
+  /* Disgusting hack.  */
+  if (dir_no == T_PRAGMA)
+    pfile->buffer->inc = pfile->buffer->prev->inc;
   start_directive (pfile);
   /* We don't want a leading # to be interpreted as a directive.  */
   pfile->buffer->saved_flags = 0;
@@ -488,6 +478,8 @@ run_directive (pfile, dir_no, buf, count)
     prepare_directive_trad (pfile);
   (void) (*pfile->directive->handler) (pfile);
   end_directive (pfile, 1);
+  if (dir_no == T_PRAGMA)
+    pfile->buffer->inc = NULL;
   _cpp_pop_buffer (pfile);
 }
 
@@ -504,16 +496,7 @@ lex_macro_node (pfile)
      In C++, it may not be any of the "named operators" either,
      per C++98 [lex.digraph], [lex.key].
      Finally, the identifier may not have been poisoned.  (In that case
-     the lexer has issued the error message for us.)
-
-     Note that if we're copying comments into macro expansions, we
-     could encounter comment tokens here, so eat them all up first.  */
-
-  if (! CPP_OPTION (pfile, discard_comments_in_macro_exp))
-    {
-      while (token->type == CPP_COMMENT)
-       token = _cpp_lex_token (pfile);
-    }
+     the lexer has issued the error message for us.)  */
 
   if (token->type == CPP_NAME)
     {
@@ -547,6 +530,11 @@ do_define (pfile)
 
   if (node)
     {
+      /* If we have been requested to expand comments into macros,
+        then re-enable saving of comments.  */
+      pfile->state.save_comments =
+       ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+
       if (_cpp_create_definition (pfile, node))
        if (pfile->cb.define)
          (*pfile->cb.define) (pfile, pfile->directive_line, node);
@@ -570,6 +558,9 @@ do_undef (pfile)
       if (node->flags & NODE_WARN)
        cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
 
+      if (CPP_OPTION (pfile, warn_unused_macros))
+       _cpp_warn_if_unused_macro (pfile, node, NULL);
+
       _cpp_free_definition (node);
     }
   check_eol (pfile);
@@ -592,7 +583,7 @@ glue_header_name (pfile)
   buffer = (unsigned char *) xmalloc (capacity);
   for (;;)
     {
-      token = cpp_get_token (pfile);
+      token = get_token_no_padding (pfile);
 
       if (token->type == CPP_GREATER || token->type == CPP_EOF)
        break;
@@ -644,7 +635,7 @@ parse_include (pfile)
     dir = pfile->directive->name;
 
   /* Allow macro expansion.  */
-  header = cpp_get_token (pfile);
+  header = get_token_no_padding (pfile);
   if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
     {
       if (header->type != CPP_LESS)
@@ -665,6 +656,7 @@ parse_include (pfile)
       return NULL;
     }
 
+  check_eol (pfile);
   return header;
 }
 
@@ -674,40 +666,25 @@ do_include_common (pfile, type)
      cpp_reader *pfile;
      enum include_type type;
 {
-  const cpp_token *header;
+  const cpp_token *header = parse_include (pfile);
+  if (!header)
+    return;
 
-  /* For #include_next, if this is the primary source file, warn and
-     use the normal search logic.  */
-  if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
-    {
-      cpp_error (pfile, DL_WARNING, "#include_next in primary source file");
-      type = IT_INCLUDE;
-    }
-  else if (type == IT_IMPORT && CPP_OPTION (pfile, warn_import))
+  /* Prevent #include recursion.  */
+  if (pfile->line_maps.depth >= CPP_STACK_MAX)
     {
-      CPP_OPTION (pfile, warn_import) = 0;
-      cpp_error (pfile, DL_WARNING,
-          "#import is obsolete, use an #ifndef wrapper in the header file");
+      cpp_error (pfile, DL_ERROR, "#include nested too deeply");
+      return;
     }
 
-  header = parse_include (pfile);
-  if (header)
-    {
-      /* Prevent #include recursion.  */
-      if (pfile->line_maps.depth >= CPP_STACK_MAX)
-       cpp_error (pfile, DL_ERROR, "#include nested too deeply");
-      else
-       {
-         check_eol (pfile);
-         /* Get out of macro context, if we are.  */
-         skip_rest_of_line (pfile);
-         if (pfile->cb.include)
-           (*pfile->cb.include) (pfile, pfile->directive_line,
-                                 pfile->directive->name, header);
+  /* Get out of macro context, if we are.  */
+  skip_rest_of_line (pfile);
 
-         _cpp_execute_include (pfile, header, type);
-       }
-    }
+  if (pfile->cb.include)
+    (*pfile->cb.include) (pfile, pfile->directive_line,
+                         pfile->directive->name, header);
+
+  _cpp_execute_include (pfile, header, type);
 }
 
 static void
@@ -721,6 +698,13 @@ static void
 do_import (pfile)
      cpp_reader *pfile;
 {
+  if (CPP_OPTION (pfile, warn_import))
+    {
+      CPP_OPTION (pfile, warn_import) = 0;
+      cpp_error (pfile, DL_WARNING,
+   "#import is obsolete, use an #ifndef wrapper in the header file");
+    }
+
   do_include_common (pfile, IT_IMPORT);
 }
 
@@ -728,7 +712,17 @@ static void
 do_include_next (pfile)
      cpp_reader *pfile;
 {
-  do_include_common (pfile, IT_INCLUDE_NEXT);
+  enum include_type type = IT_INCLUDE_NEXT;
+
+  /* If this is the primary source file, warn and use the normal
+     search logic.  */
+  if (! pfile->buffer->prev)
+    {
+      cpp_error (pfile, DL_WARNING,
+                "#include_next in primary source file");
+      type = IT_INCLUDE;
+    }
+  do_include_common (pfile, type);
 }
 
 /* Subroutine of do_linemarker.  Read possible flags after file name.
@@ -1101,6 +1095,85 @@ _cpp_init_internal_pragmas (pfile)
   cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
 }
 
+/* Return the number of registered pragmas in PE.  */
+
+static int
+count_registered_pragmas (pe)
+     struct pragma_entry *pe;
+{
+  int ct = 0;
+  for (; pe != NULL; pe = pe->next)
+    {
+      if (pe->is_nspace)
+       ct += count_registered_pragmas (pe->u.space);
+      ct++;
+    }
+  return ct;
+}
+
+/* Save into SD the names of the registered pragmas referenced by PE,
+   and return a pointer to the next free space in SD.  */
+
+static char **
+save_registered_pragmas (pe, sd)
+     struct pragma_entry *pe;
+     char **sd;
+{
+  for (; pe != NULL; pe = pe->next)
+    {
+      if (pe->is_nspace)
+       sd = save_registered_pragmas (pe->u.space, sd);
+      *sd++ = xmemdup (HT_STR (&pe->pragma->ident),
+                      HT_LEN (&pe->pragma->ident),
+                      HT_LEN (&pe->pragma->ident) + 1);
+    }
+  return sd;
+}
+
+/* Return a newly-allocated array which saves the names of the
+   registered pragmas.  */
+
+char **
+_cpp_save_pragma_names (pfile)
+     cpp_reader *pfile;
+{
+  int ct = count_registered_pragmas (pfile->pragmas);
+  char **result = xnewvec (char *, ct);
+  (void) save_registered_pragmas (pfile->pragmas, result);
+  return result;
+}
+
+/* Restore from SD the names of the registered pragmas referenced by PE,
+   and return a pointer to the next unused name in SD.  */
+
+static char **
+restore_registered_pragmas (pfile, pe, sd)
+     cpp_reader *pfile;
+     struct pragma_entry *pe;
+     char **sd;
+{
+  for (; pe != NULL; pe = pe->next)
+    {
+      if (pe->is_nspace)
+       sd = restore_registered_pragmas (pfile, pe->u.space, sd);
+      pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd));
+      free (*sd);
+      sd++;
+    }
+  return sd;
+}
+
+/* Restore the names of the registered pragmas from SAVED.  */
+
+void
+_cpp_restore_pragma_names (pfile, saved)
+     cpp_reader *pfile;
+     char **saved;
+{
+  (void) restore_registered_pragmas (pfile, pfile->pragmas, saved);
+  free (saved);
+}
+
 /* Pragmata handling.  We handle some, and pass the rest on to the
    front end.  C99 defines three pragmas and says that no macro
    expansion is to be performed on them; whether or not macro
@@ -1155,7 +1228,8 @@ static void
 do_pragma_once (pfile)
      cpp_reader *pfile;
 {
-  cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
+  if (CPP_OPTION (pfile, warn_deprecated))
+    cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
 
   if (pfile->buffer->prev == NULL)
     cpp_error (pfile, DL_WARNING, "#pragma once in main file");
@@ -1306,7 +1380,45 @@ destringize_and_run (pfile, in)
     }
   *dest = '\0';
 
-  run_directive (pfile, T_PRAGMA, result, dest - result);
+  /* Ugh; an awful kludge.  We are really not set up to be lexing
+     tokens when in the middle of a macro expansion.  Use a new
+     context to force cpp_get_token to lex, and so skip_rest_of_line
+     doesn't go beyond the end of the text.  Also, remember the
+     current lexing position so we can return to it later.
+
+     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);
+    free (pfile->context);
+    pfile->context = saved_context;
+    pfile->cur_token = saved_cur_token;
+    pfile->cur_run = saved_cur_run;
+    pfile->line--;
+  }
+
+  /* See above comment.  For the moment, we'd like
+
+     token1 _Pragma ("foo") token2
+
+     to be output as
+
+               token1
+               # 7 "file.c"
+               #pragma foo
+               # 7 "file.c"
+                              token2
+
+      Getting the line markers is a little tricky.  */
+  if (pfile->cb.line_change)
+    (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
 }
 
 /* Handle the _Pragma operator.  */
@@ -1316,36 +1428,19 @@ _cpp_do__Pragma (pfile)
 {
   const cpp_token *string = get__Pragma_string (pfile);
 
-  if (!string)
+  if (string)
+    destringize_and_run (pfile, &string->val.str);
+  else
     cpp_error (pfile, DL_ERROR,
               "_Pragma takes a parenthesized string literal");
-  else
-    {
-      /* Ideally, we'd like
-                       token1 _Pragma ("foo") token2
-        to be output as
-                       token1
-                       # 7 "file.c"
-                       #pragma foo
-                       # 7 "file.c"
-                                              token2
-        Getting these correct line markers is a little tricky.  */
-
-      unsigned int orig_line = pfile->line;
-      destringize_and_run (pfile, &string->val.str);
-      pfile->line = orig_line;
-      pfile->buffer->saved_flags = BOL;
-    }
 }
 
-/* Just ignore #sccs, on systems where we define it at all.  */
-#ifdef SCCS_DIRECTIVE
+/* Just ignore #sccs on all systems.  */
 static void
 do_sccs (pfile)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
 {
 }
-#endif
 
 /* Handle #ifdef.  */
 static void
@@ -1359,10 +1454,11 @@ do_ifdef (pfile)
       const cpp_hashnode *node = lex_macro_node (pfile);
 
       if (node)
-       skip = node->type != NT_MACRO;
-
-      if (node)
-       check_eol (pfile);
+       {
+         skip = node->type != NT_MACRO;
+         _cpp_mark_macro_used (node);
+         check_eol (pfile);
+       }
     }
 
   push_conditional (pfile, skip, T_IFDEF, 0);
@@ -1379,11 +1475,13 @@ do_ifndef (pfile)
   if (! pfile->state.skipping)
     {
       node = lex_macro_node (pfile);
-      if (node)
-       skip = node->type == NT_MACRO;
 
       if (node)
-       check_eol (pfile);
+       {
+         skip = node->type == NT_MACRO;
+         _cpp_mark_macro_used (node);
+         check_eol (pfile);
+       }
     }
 
   push_conditional (pfile, skip, T_IFNDEF, node);
@@ -1682,8 +1780,8 @@ find_answer (node, candidate)
 }
 
 /* Test an assertion within a preprocessor conditional.  Returns
-   non-zero on failure, zero on success.  On success, the result of
-   the test is written into VALUE.  */
+   nonzero on failure, zero on success.  On success, the result of
+   the test is written into VALUE, otherwise the value 0.  */
 int
 _cpp_test_assertion (pfile, value)
      cpp_reader *pfile;
@@ -1693,6 +1791,11 @@ _cpp_test_assertion (pfile, value)
   cpp_hashnode *node;
 
   node = parse_assertion (pfile, &answer, T_IF);
+
+  /* For recovery, an erroneous assertion expression is handled as a
+     failing assertion.  */
+  *value = 0;
+
   if (node)
     *value = (node->type == NT_ASSERTION &&
              (answer == 0 || *find_answer (node, answer) != 0));
@@ -1934,9 +2037,6 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
 
   pfile->buffer = new;
 
-  if (CPP_OPTION (pfile, traditional))
-    _cpp_set_trad_context (pfile);
-
   return new;
 }
 
@@ -1981,12 +2081,9 @@ _cpp_pop_buffer (pfile)
            _cpp_maybe_push_include_file (pfile);
        }
     }
-
-  if (pfile->buffer && CPP_OPTION (pfile, traditional))
-    _cpp_set_trad_context (pfile);
 }
 
-/* Enter all recognised directives in the hash table.  */
+/* Enter all recognized directives in the hash table.  */
 void
 _cpp_init_directives (pfile)
      cpp_reader *pfile;
@@ -1997,6 +2094,7 @@ _cpp_init_directives (pfile)
   for (i = 0; i < (unsigned int) N_DIRECTIVES; i++)
     {
       node = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
-      node->directive_index = i + 1;
+      node->is_directive = 1;
+      node->directive_index = i;
     }
 }