OSDN Git Service

(do_include): Diagnose #import and #include_next if pedantic and if
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 8f8c64a..b9c2190 100644 (file)
@@ -1,5 +1,5 @@
 /* Lexical analyzer for C and Objective C.
-   Copyright (C) 1987, 88, 89, 92, 94, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92, 94, 95, 1996 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 #include <stdio.h>
@@ -30,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "c-tree.h"
 #include "flags.h"
 #include "c-parse.h"
+#include "c-pragma.h"
 
 #include <ctype.h>
 
@@ -396,14 +398,30 @@ check_newline ()
              && getc (finput) == 'a'
              && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
            {
+             while (c == ' ' || c == '\t')
+               c = getc (finput);
+             if (c == '\n')
+               return c;
 #ifdef HANDLE_SYSV_PRAGMA
-             return handle_sysv_pragma (finput, c);
+             ungetc (c, finput);
+             token = yylex ();
+             if (token != IDENTIFIER)
+               goto skipline;
+             return handle_sysv_pragma (finput, token);
 #else /* !HANDLE_SYSV_PRAGMA */
 #ifdef HANDLE_PRAGMA
-             HANDLE_PRAGMA (finput);
+             ungetc (c, finput);
+             token = yylex ();
+             if (token != IDENTIFIER)
+               goto skipline;
+             if (HANDLE_PRAGMA (finput, yylval.ttype))
+               {
+                 c = getc (finput);
+                 return c;
+               }
 #endif /* HANDLE_PRAGMA */
-             goto skipline;
 #endif /* !HANDLE_SYSV_PRAGMA */
+             goto skipline;
            }
        }
 
@@ -416,11 +434,8 @@ check_newline ()
              && getc (finput) == 'e'
              && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
            {
-#ifdef DWARF_DEBUGGING_INFO
-             if ((debug_info_level == DINFO_LEVEL_VERBOSE)
-                 && (write_symbols == DWARF_DEBUG))
-               dwarfout_define (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+             if (c != '\n')
+               debug_define (lineno, get_directive_line (finput));
              goto skipline;
            }
        }
@@ -432,11 +447,8 @@ check_newline ()
              && getc (finput) == 'f'
              && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
            {
-#ifdef DWARF_DEBUGGING_INFO
-             if ((debug_info_level == DINFO_LEVEL_VERBOSE)
-                 && (write_symbols == DWARF_DEBUG))
-               dwarfout_undef (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+             if (c != '\n')
+               debug_undef (lineno, get_directive_line (finput));
              goto skipline;
            }
        }
@@ -588,12 +600,7 @@ linenum:
              p->name = input_filename;
              input_file_stack = p;
              input_file_stack_tick++;
-#ifdef DWARF_DEBUGGING_INFO
-             if (debug_info_level == DINFO_LEVEL_VERBOSE
-                 && write_symbols == DWARF_DEBUG)
-               dwarfout_start_new_source_file (input_filename);
-#endif /* DWARF_DEBUGGING_INFO */
-
+             debug_start_source_file (input_filename);
              used_up = 1;
            }
          else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
@@ -605,11 +612,7 @@ linenum:
                  input_file_stack = p->next;
                  free (p);
                  input_file_stack_tick++;
-#ifdef DWARF_DEBUGGING_INFO
-                 if (debug_info_level == DINFO_LEVEL_VERBOSE
-                     && write_symbols == DWARF_DEBUG)
-                   dwarfout_resume_previous_source_file (input_file_stack->line);
-#endif /* DWARF_DEBUGGING_INFO */
+                 debug_end_source_file (input_file_stack->line);
                }
              else
                error ("#-lines for entering and leaving files don't match");
@@ -664,37 +667,30 @@ linenum:
 
   /* skip the rest of this line.  */
  skipline:
-  if (c == '\n')
-    return c;
-  while ((c = getc (finput)) != EOF && c != '\n');
+  while (c != '\n' && c != EOF)
+    c = getc (finput);
   return c;
 }
 \f
 #ifdef HANDLE_SYSV_PRAGMA
 
 /* Handle a #pragma directive.  INPUT is the current input stream,
-   and C is a character to reread.  Processes the entire input line
-   and returns a character for the caller to reread: either \n or EOF.  */
+   and TOKEN is the token we read after `#pragma'.  Processes the entire input
+   line and returns a character for the caller to reread: either \n or EOF.  */
 
 /* This function has to be in this file, in order to get at
    the token types.  */
 
 int
-handle_sysv_pragma (input, c)
+handle_sysv_pragma (input, token)
      FILE *input;
-     int c;
+     register int token;
 {
+  register int c;
+
   for (;;)
     {
-      while (c == ' ' || c == '\t')
-       c = getc (input);
-      if (c == '\n' || c == EOF)
-       {
-         handle_pragma_token (0, 0);
-         return c;
-       }
-      ungetc (c, input);
-      switch (yylex ())
+      switch (token)
        {
        case IDENTIFIER:
        case TYPENAME:
@@ -705,10 +701,21 @@ handle_sysv_pragma (input, c)
        default:
          handle_pragma_token (token_buffer, 0);
        }
+
       if (nextchar >= 0)
        c = nextchar, nextchar = -1;
       else
        c = getc (input);
+
+      while (c == ' ' || c == '\t')
+       c = getc (input);
+      if (c == '\n' || c == EOF)
+       {
+         handle_pragma_token (0, 0);
+         return c;
+       }
+      ungetc (c, input);
+      token = yylex ();
     }
 }
 
@@ -954,11 +961,6 @@ yylex ()
       value = ENDFILE;
       break;
 
-    case '$':
-      if (dollars_in_ident)
-       goto letter;
-      return '$';
-
     case 'L':
       /* Capital L may start a wide-string or wide-character constant.  */
       {
@@ -993,7 +995,7 @@ yylex ()
              goto string_constant;
            }
          ungetc(c, finput);
-         /* Fall through to treat '@' as the start of an indentifier.  */
+         /* Fall through to treat '@' as the start of an identifier.  */
        }
 
     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
@@ -1009,6 +1011,7 @@ yylex ()
     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
     case 'z':
     case '_':
+    case '$':
     letter:
       p = token_buffer;
       while (isalnum (c) || c == '_' || c == '$' || c == '@')
@@ -1016,8 +1019,13 @@ yylex ()
          /* Make sure this char really belongs in an identifier.  */
          if (c == '@' && ! doing_objc_thang)
            break;
-         if (c == '$' && ! dollars_in_ident)
-           break;
+         if (c == '$')
+           {
+             if (! dollars_in_ident)
+               error ("`$' in identifier");
+             else if (pedantic)
+               pedwarn ("`$' in identifier");
+           }
 
          if (p >= token_buffer + maxtoken)
            p = extend_token_buffer (p);
@@ -1107,7 +1115,23 @@ yylex ()
 
       break;
 
-    case '0':  case '1':  case '2':  case '3':  case '4':
+    case '0':  case '1':
+      {
+       int next_c;
+       /* Check first for common special case:  single-digit 0 or 1.  */
+
+       next_c = getc (finput);
+       ungetc (next_c, finput);        /* Always undo this lookahead.  */
+       if (!isalnum (next_c) && next_c != '.')
+         {
+           token_buffer[0] = (char)c,  token_buffer[1] = '\0';
+           yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
+           value = CONSTANT;
+           break;
+         }
+       /*FALLTHRU*/
+      }
+    case '2':  case '3':  case '4':
     case '5':  case '6':  case '7':  case '8':  case '9':
     case '.':
       {
@@ -1272,7 +1296,7 @@ yylex ()
        if (floatflag != NOT_FLOAT)
          {
            tree type = double_type_node;
-           int garbage_chars = 0, exceeds_double = 0;
+           int exceeds_double = 0;
            int imag = 0;
            REAL_VALUE_TYPE value;
            jmp_buf handler;
@@ -1408,19 +1432,6 @@ yylex ()
                  }
              }
 #endif
-           garbage_chars = 0;
-           while (isalnum (c) || c == '.' || c == '_'
-                  || (!flag_traditional && (c == '+' || c == '-')
-                      && (p[-1] == 'e' || p[-1] == 'E')))
-             {
-               if (p >= token_buffer + maxtoken - 3)
-                 p = extend_token_buffer (p);
-               *p++ = c;
-               c = getc (finput);
-               garbage_chars++;
-             }
-           if (garbage_chars > 0)
-             error ("garbage at end of number");
 
            /* If the result is not a number, assume it must have been
               due to some error message above, so silently convert
@@ -1430,13 +1441,11 @@ yylex ()
 
            /* Create a node with determined type and value.  */
            if (imag)
-             yylval.ttype = build_complex (convert (type, integer_zero_node),
+             yylval.ttype = build_complex (NULL_TREE,
+                                           convert (type, integer_zero_node),
                                            build_real (type, value));
            else
              yylval.ttype = build_real (type, value);
-
-           ungetc (c, finput);
-           *p = 0;
          }
        else
          {
@@ -1477,32 +1486,13 @@ yylex ()
                    spec_imag = 1;
                  }
                else
-                 {
-                   if (isalnum (c) || c == '.' || c == '_'
-                       || (!flag_traditional && (c == '+' || c == '-')
-                           && (p[-1] == 'e' || p[-1] == 'E')))
-                     {
-                       error ("garbage at end of number");
-                       while (isalnum (c) || c == '.' || c == '_'
-                              || (!flag_traditional && (c == '+' || c == '-')
-                                  && (p[-1] == 'e' || p[-1] == 'E')))
-                         {
-                           if (p >= token_buffer + maxtoken - 3)
-                             p = extend_token_buffer (p);
-                           *p++ = c;
-                           c = getc (finput);
-                         }
-                     }
-                   break;
-                 }
+                 break;
                if (p >= token_buffer + maxtoken - 3)
                  p = extend_token_buffer (p);
                *p++ = c;
                c = getc (finput);
              }
 
-           ungetc (c, finput);
-
            /* If the constant is not long long and it won't fit in an
               unsigned long, or if the constant is long long and won't fit
               in an unsigned long long, then warn that the constant is out
@@ -1621,8 +1611,9 @@ yylex ()
                if (TYPE_PRECISION (type)
                    <= TYPE_PRECISION (integer_type_node))
                  yylval.ttype
-                   = build_complex (integer_zero_node,
-                                    convert (integer_type_node, yylval.ttype));
+                   = build_complex (NULL_TREE, integer_zero_node,
+                                    convert (integer_type_node,
+                                             yylval.ttype));
                else
                  error ("complex integer constant is too wide for `complex int'");
              }
@@ -1638,10 +1629,16 @@ yylex ()
              }
            else
              TREE_TYPE (yylval.ttype) = type;
-
-           *p = 0;
          }
 
+       ungetc (c, finput);
+       *p = 0;
+
+       if (isalnum (c) || c == '.' || c == '_' || c == '$'
+           || (!flag_traditional && (c == '-' || c == '+')
+               && (p[-1] == 'e' || p[-1] == 'E')))
+         error ("missing white space after number `%s'", token_buffer);
+
        value = CONSTANT; break;
       }
 
@@ -1879,6 +1876,7 @@ yylex ()
     case '-':
     case '&':
     case '|':
+    case ':':
     case '<':
     case '>':
     case '*':
@@ -1956,8 +1954,28 @@ yylex ()
              c = RSHIFT;
              goto combine;
            }
-       else if ((c == '-') && (c1 == '>'))
-         { value = POINTSAT; goto done; }
+       else
+         switch (c)
+           {
+           case '-':
+             if (c1 == '>')
+               { value = POINTSAT; goto done; }
+             break;
+           case ':':
+             if (c1 == '>')
+               { value = ']'; goto done; }
+             break;
+           case '<':
+             if (c1 == '%')
+               { value = '{'; goto done; }
+             if (c1 == ':')
+               { value = '['; goto done; }
+             break;
+           case '%':
+             if (c1 == '>')
+               { value = '}'; goto done; }
+             break;
+           }
        ungetc (c1, finput);
        token_buffer[1] = 0;