Patch to improve cpplib's C++ support

Jason Merrill jason@cygnus.com
Sat Jul 10 16:24:00 GMT 1999


This patch enables the C++ frontend to use cpplib to defer scanning of
method bodies and the like, rather than its internal code.   As a result,
the frontend can take advantage of cpplib's tokenization work.

Sat Jul 10 16:16:09 1999  Jason Merrill  <jason@yorick.cygnus.com>

	* cpplib.c (cpp_unget): New fn.

Sat Jul 10 16:16:09 1999  Michael Tiemann  <tiemann@holodeck.cygnus.com>

	* cpplib.h (struct cpp_buffer): Added redirected_input_p for
	better C++ tokenization.
	* cpplib.c (cpp_get_token): Return CPP_EOF if redirected_input_p.
	Also, support C++ tokenization for ->* operator.
	Also, support tokenization for GCC's <? and >? operators.
	Also, support C++ tokenization for .* operator.

	* c-common.c (cpp_token): Make non-static.

Index: c-common.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-common.c,v
retrieving revision 1.58
diff -c -p -r1.58 c-common.c
*** c-common.c	1999/07/06 12:34:41	1.58
--- c-common.c	1999/07/10 22:53:52
*************** Boston, MA 02111-1307, USA.  */
*** 34,40 ****
  #include "cpplib.h"
  cpp_reader  parse_in;
  cpp_options parse_options;
! static enum cpp_token cpp_token;
  #endif
  
  #ifndef WCHAR_TYPE_SIZE
--- 34,40 ----
  #include "cpplib.h"
  cpp_reader  parse_in;
  cpp_options parse_options;
! enum cpp_token cpp_token;
  #endif
  
  #ifndef WCHAR_TYPE_SIZE
Index: cpplib.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cpplib.c,v
retrieving revision 1.82
diff -c -p -r1.82 cpplib.c
*** cpplib.c	1999/06/07 10:35:26	1.82
--- cpplib.c	1999/07/10 23:21:37
*************** cpp_get_token (pfile)
*** 2029,2035 ****
      handle_eof:
        if (CPP_BUFFER (pfile)->seen_eof)
  	{
! 	  if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == CPP_NULL_BUFFER (pfile))
  	    return CPP_EOF;
  
  	  cpp_pop_buffer (pfile);
--- 2059,2068 ----
      handle_eof:
        if (CPP_BUFFER (pfile)->seen_eof)
  	{
! 	  if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == CPP_NULL_BUFFER (pfile)
! 	      /* If we've been reading from redirected input, the
! 		 frontend will pop the buffer.  */
! 	      || CPP_BUFFER (pfile)->redirected_input_p)
  	    return CPP_EOF;
  
  	  cpp_pop_buffer (pfile);
*************** cpp_get_token (pfile)
*** 2172,2179 ****
  	  c2 = PEEKC ();
  	  if (c2 == '-' && opts->chill)
  	    goto comment;  /* Chill style comment */
! 	  if (c2 == '-' || c2 == '=' || c2 == '>')
  	    goto op2;
  	  goto randomchar;
  
  	case '<':
--- 2205,2229 ----
  	  c2 = PEEKC ();
  	  if (c2 == '-' && opts->chill)
  	    goto comment;  /* Chill style comment */
! 	  if (c2 == '-' || c2 == '=')
  	    goto op2;
+ 	  if (c2 == '>')
+ 	    {
+ 	      if (opts->cplusplus && PEEKN (1) == '*')
+ 		{
+ 		  /* In C++, there's a ->* operator.  */
+ 		op3:
+ 		  token = CPP_OTHER;
+ 		  pfile->only_seen_white = 0;
+ 		  CPP_RESERVE (pfile, 4);
+ 		  CPP_PUTC_Q (pfile, c);
+ 		  CPP_PUTC_Q (pfile, GETC ());
+ 		  CPP_PUTC_Q (pfile, GETC ());
+ 		  CPP_NUL_TERMINATE_Q (pfile);
+ 		  return token;
+ 		}
+ 	      goto op2;
+ 	    }
  	  goto randomchar;
  
  	case '<':
*************** cpp_get_token (pfile)
*** 2219,2225 ****
  	  c2 = PEEKC ();
  	  if (c2 == '=')
  	    goto op2;
! 	  if (c2 != c)
  	    goto randomchar;
  	  FORWARD(1);
  	  CPP_RESERVE (pfile, 4);
--- 2269,2276 ----
  	  c2 = PEEKC ();
  	  if (c2 == '=')
  	    goto op2;
! 	  /* GNU C and C++ support MIN and MAX operators <? and >?.  */
! 	  if (c2 != c && c2 != '?')
  	    goto randomchar;
  	  FORWARD(1);
  	  CPP_RESERVE (pfile, 4);
*************** cpp_get_token (pfile)
*** 2241,2246 ****
--- 2292,2302 ----
  	      c = GETC ();
  	      goto number;
  	    }
+ 
+ 	  /* In C++ there's a .* operator.  */
+ 	  if (opts->cplusplus && c2 == '*')
+ 	    goto op2;
+ 
  	  if (c2 == '.' && PEEKN(1) == '.')
  	    {
  	      CPP_RESERVE(pfile, 4);
*************** parse_name (pfile, c)
*** 2549,2555 ****
  /* Parse a string starting with C.  A single quoted string is treated
     like a double -- some programs (e.g., troff) are perverse this way.
     (However, a single quoted string is not allowed to extend over
!    multiple lines.  */
  static void
  parse_string (pfile, c)
       cpp_reader *pfile;
--- 2605,2611 ----
  /* Parse a string starting with C.  A single quoted string is treated
     like a double -- some programs (e.g., troff) are perverse this way.
     (However, a single quoted string is not allowed to extend over
!    multiple lines.)  */
  static void
  parse_string (pfile, c)
       cpp_reader *pfile;
*************** parse_goto_mark (pfile)
*** 2928,2933 ****
--- 2984,3010 ----
  
    ip->cur = ip->buf + ip->mark;
    ip->mark = -1;
+ }
+ 
+ /* Put back I characters into the current input buffer of PFILE.  In C++,
+    when we start parsing saved text for a method definition, we might have
+    stuff left over in the token buffer from lookahead, and we need to put
+    it back into the file it came from before we can read from the new
+    buffer.  */
+ 
+ void
+ cpp_unget (pfile, i)
+      cpp_reader *pfile;
+      int i;
+ {
+   if ((CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->buf) < i
+       || CPP_WRITTEN (pfile) < i)
+     {
+       cpp_fatal (pfile, "can't unget");
+       return;
+     }
+   FORWARD (-i);
+   CPP_ADJUST_WRITTEN (pfile, -i);
  }
  
  void
Index: cpplib.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cpplib.h,v
retrieving revision 1.38
diff -c -p -r1.38 cpplib.h
*** cpplib.h	1999/05/10 15:24:35	1.38
--- cpplib.h	1999/07/10 22:53:53
*************** extern int cpp_handle_options PARAMS ((c
*** 81,86 ****
--- 81,87 ----
  extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
  extern void cpp_skip_hspace PARAMS((cpp_reader *));
  extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
+ extern void cpp_unget PARAMS ((cpp_reader *, int));
  
  /* This frees resources used by PFILE. */
  extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
*************** struct cpp_buffer
*** 136,141 ****
--- 137,146 ----
       escapes are used only in macro buffers, and backslash-newline is removed
       from macro expansion text in collect_expansion and/or macarg.  */
    char has_escapes;
+ 
+   /* Used for C++: True if buffer is really used to implement redirected
+      input (such as for default argument and/or template parsing).  */
+   char redirected_input_p;
  };
  
  struct file_name_map_list;


More information about the Gcc-patches mailing list