This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Improved HANDLE_PRAGMA macro and new INSERT_ATTRIBUTES macro


Hi,

  I would like to submit the following patch to EGCS.  This patch:

* Provides a way for the HANDLE_PRAGMA macro to work when USE_CPPLIB
  is defined, by passing as the first argument a pointer to a function
  that can be used to retrieve and restore characters to the input 
  stream.

* Provides a new macro called INSERT_ATTRIBUTES which if defined, can
  be used by backends to add attributes to decls as they are being
  created.  This allows backends for example, to implment a pragma by
  generating the attributes that are the equivalent to the pragma.

This patch would be useful for the i386 port and the improvment of the
Cygwin32 environment.

Cheers
	Nick


Fri Aug 14 17:25:29 1998  Nick Clifton  <nickc@cygnus.com>

	* c-lex.c (check_newline):  Call HANDLE_PRAGMA before
	HANDLE_SYSV_PRAGMA if both are defined.  Generate warning messages
	if unknown pragmas are encountered.
	(handle_sysv_pragma): Interpret return code from
	handle_pragma_token ().  Return success/failure indication rather
	than next unprocessed character. 
	(get_ungetc): New function: retrieves or restores characters
	to/from the input stream.  Defined when HANDLE_PRAGMA and
	USE_CPPLIB are defined. 
	
	* c-pragma.c (handle_pragma_token): Return success/failure status
	of the parse.
	
	* c-pragma.h: Change prototype of handle_pragma_token().

	* varasm.c: (handle_pragma_weak): Only create this function if
	HANDLE_PRAGMA_WEAK is defined.
	
	* tm.texi (HANDLE_PRAGMA): Document the use of HANDLE_PRAGMA when
	USE_CPPLIB is enabled.

Index: c-lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-lex.c,v
retrieving revision 1.28
diff -p -w -r1.28 c-lex.c
*** c-lex.c	1998/07/27 12:51:56	1.28
--- c-lex.c	1998/08/15 00:01:39
*************** extend_token_buffer (p)
*** 479,484 ****
--- 479,498 ----
    return token_buffer + offset;
  }
  
+ #if defined HANDLE_PRAGMA && defined USE_CPPLIB
+ /* If passed an argument of -2 retrieve a character from the input stream.
+    If passed any other value (including EOF), stuff that value back into the
+    input stream.  */
+ int get_ungetc (arg)
+      int arg;
+ {
+   if (arg == -2)
+     return GETC();
+   else
+     UNGETC (arg);
+ }
+ #endif
+ 
  /* At the beginning of a line, increment the line number
     and process any #-directive on this line.
     If the line is a #-directive, read the entire line and return a newline.
*************** check_newline ()
*** 530,563 ****
  		c = GETC ();
  	      if (c == '\n')
  		return c;
! #ifdef HANDLE_SYSV_PRAGMA
  	      UNGETC (c);
  	      token = yylex ();
  	      if (token != IDENTIFIER)
  		goto skipline;
! 	      return handle_sysv_pragma (token);
! #else /* !HANDLE_SYSV_PRAGMA */
  #ifdef HANDLE_PRAGMA
  #if !USE_CPPLIB
- 	      UNGETC (c);
- 	      token = yylex ();
- 	      if (token != IDENTIFIER)
- 		goto skipline;
  	      if (nextchar >= 0)
- 		c = nextchar, nextchar = -1;
- 	      else
- 		c = GETC ();
- 	      ungetc (c, finput);
- 	      if (HANDLE_PRAGMA (finput, yylval.ttype))
  		{
! 		  c = GETC ();
! 		  return c;
  		}
  #else
! 	      ??? do not know what to do ???;
! #endif /* !USE_CPPLIB */
  #endif /* HANDLE_PRAGMA */
  #endif /* !HANDLE_SYSV_PRAGMA */
  	      goto skipline;
  	    }
  	}
--- 544,588 ----
  		c = GETC ();
  	      if (c == '\n')
  		return c;
! 
! #if defined HANDLE_PRAGMA || defined HANDLE_SYSV_PRAGMA	      
  	      UNGETC (c);
  	      token = yylex ();
  	      if (token != IDENTIFIER)
  		goto skipline;
! 	      
  #ifdef HANDLE_PRAGMA
+ 	      /* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA
+ 		 (if both are defined), in order to give the back
+ 		 end a chance to override the interpretation of
+ 		 SYSV style pragmas.  */
  #if !USE_CPPLIB
  	      if (nextchar >= 0)
  		{
! 		  c = nextchar, nextchar = -1;
! 		  UNGETC (c);
  		}
+ 	      if (HANDLE_PRAGMA (finput, yylval.ttype))
+ 		return GETC ();
  #else	      
! 	      if (HANDLE_PRAGMA (get_ungetc, yylval.ttype))
! 		return GETC ();
! #endif /* USE_CPPLIB */
  #endif /* HANDLE_PRAGMA */
+ 	      
+ #ifdef HANDLE_SYSV_PRAGMA
+ 	      if (handle_sysv_pragma (token))
+ 		return GETC ();
  #endif /* !HANDLE_SYSV_PRAGMA */
+ #endif /* HANDLE_PRAGMA || HANDLE_SYSV_PRAGMA */
+ 	      
+ 	      /* Issue a warning message if we have been asked to do so.
+ 		 Ignoring unknown pragmas in system header file unless
+ 		 an explcit -Wunknown-pragmas has been given. */
+ 	      if (warn_unknown_pragmas > 1
+ 		  || (warn_unknown_pragmas && ! in_system_header))
+ 		warning ("ignoring pragma: %s", token_buffer);
+ 	      
  	      goto skipline;
  	    }
  	}
*************** handle_sysv_pragma (token)
*** 842,848 ****
  	  handle_pragma_token (token_buffer, yylval.ttype);
  	  break;
  	default:
! 	  handle_pragma_token (token_buffer, 0);
  	}
  #if !USE_CPPLIB
        if (nextchar >= 0)
--- 867,873 ----
  	  handle_pragma_token (token_buffer, yylval.ttype);
  	  break;
  	default:
! 	  handle_pragma_token (token_buffer, NULL);
  	}
  #if !USE_CPPLIB
        if (nextchar >= 0)
*************** handle_sysv_pragma (token)
*** 853,864 ****
  
        while (c == ' ' || c == '\t')
  	c = GETC ();
-       if (c == '\n' || c == EOF)
- 	{
- 	  handle_pragma_token (0, 0);
- 	  return c;
- 	}
        UNGETC (c);
        token = yylex ();
      }
  }
--- 878,888 ----
  
        while (c == ' ' || c == '\t')
  	c = GETC ();
        UNGETC (c);
+       
+       if (c == '\n' || c == EOF)
+ 	return handle_pragma_token (NULL, NULL);
+ 
        token = yylex ();
      }
  }

Index: c-pragma.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-pragma.c,v
retrieving revision 1.7
diff -p -w -r1.7 c-pragma.c
*** c-pragma.c	1998/05/28 06:47:21	1.7
--- c-pragma.c	1998/08/15 00:05:55
***************
*** 1,5 ****
  /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
!    Copyright (C) 1992, 1997 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
--- 1,5 ----
  /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
!    Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
*************** Boston, MA 02111-1307, USA.  */
*** 37,49 ****
  
  extern int maximum_field_alignment;
  
- /* File used for outputting assembler code.  */
- extern FILE *asm_out_file;
- 
  /* Handle one token of a pragma directive.  TOKEN is the
!    current token, and STRING is its printable form.  */
  
! void
  handle_pragma_token (string, token)
       char *string;
       tree token;
--- 37,48 ----
  
  extern int maximum_field_alignment;
  
  /* Handle one token of a pragma directive.  TOKEN is the
!    current token, and STRING is its printable form. 
!    Return zero if an entire pragma was parsed, but it was
!    flawed in some way.  Return non-zero in all other cases.  */
  
! int
  handle_pragma_token (string, token)
       char *string;
       tree token;
*************** handle_pragma_token (string, token)
*** 53,78 ****
    static char *value;
    static int align;
  
!   if (string == 0)
      {
        if (type == ps_pack)
  	{
  	  if (state == ps_right)
  	    maximum_field_alignment = align * 8;
  	  else
  	    warning ("malformed `#pragma pack'");
  	}
        else if (type == ps_weak)
  	{
  #ifdef HANDLE_PRAGMA_WEAK
  	  if (HANDLE_PRAGMA_WEAK)
  	    handle_pragma_weak (state, name, value);
- 
  #endif /* HANDLE_PRAGMA_WEAK */
  	}
  
        type = state = ps_start;
!       return;
      }
  
    switch (state)
--- 52,84 ----
    static char *value;
    static int align;
  
!   if (string == NULL)
      {
+       int ret_val = 1;
+       
        if (type == ps_pack)
  	{
  	  if (state == ps_right)
  	    maximum_field_alignment = align * 8;
  	  else
+ 	    {
  	      warning ("malformed `#pragma pack'");
+ 	      ret_val = 0;
  	    }
+ 	}
+       else if (type == ps_bad)
+ 	ret_val = 0;
        else if (type == ps_weak)
  	{
  #ifdef HANDLE_PRAGMA_WEAK
  	  if (HANDLE_PRAGMA_WEAK)
  	    handle_pragma_weak (state, name, value);
  #endif /* HANDLE_PRAGMA_WEAK */
  	}
  
        type = state = ps_start;
!       
!       return ret_val;
      }
  
    switch (state)
*************** handle_pragma_token (string, token)
*** 82,105 ****
  	{
  	  if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
  	    type = state = ps_pack;
  	  else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
  	    type = state = ps_weak;
  	  else
- 	    {
  	      type = state = ps_done;
- 
- 	      /* Issue a warning message if we have been asked to do so.
- 		 Ignoring unknown pragmas in system header file unless          
- 		 an explcit -Wunknown-pragmas has been given. */                
- 	      if (warn_unknown_pragmas > 1
- 		  || (warn_unknown_pragmas && ! in_system_header))
- 		warning ("ignoring pragma: %s", string);
  	    }
- 	}
        else
  	type = state = ps_done;
        break;
  
      case ps_weak:
        if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  	{
--- 88,105 ----
  	{
  	  if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
  	    type = state = ps_pack;
+ #ifdef HANDLE_PRAGMA_WEAK
  	  else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
  	    type = state = ps_weak;
+ #endif	  
  	  else
  	    type = state = ps_done;
  	}
        else
  	type = state = ps_done;
        break;
        
+ #ifdef HANDLE_PRAGMA_WEAK
      case ps_weak:
        if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  	{
*************** handle_pragma_token (string, token)
*** 109,114 ****
--- 109,115 ----
        else
  	state = ps_bad;
        break;
+ #endif
        
      case ps_name:
        state = (strcmp (string, "=") ? ps_bad : ps_equals);
*************** handle_pragma_token (string, token)
*** 177,181 ****
--- 178,184 ----
      default:
        abort ();
      }
+ 
+   return 1;
  }
  #endif /* HANDLE_SYSV_PRAGMA */

Index: c-pragma.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-pragma.h,v
retrieving revision 1.2
diff -p -w -r1.2 c-pragma.h
*** c-pragma.h	1998/04/03 16:33:29	1.2
--- c-pragma.h	1998/08/15 00:06:03
***************
*** 1,5 ****
  /* Pragma related interfaces.
!    Copyright (C) 1995 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
--- 1,5 ----
  /* Pragma related interfaces.
!    Copyright (C) 1995, 1998 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
*************** along with GNU CC; see the file COPYING.
*** 18,23 ****
--- 18,25 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
+ #ifdef HANDLE_SYSV_PRAGMA
+ 
  /* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are
     defined.  */
  #if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF)
*************** enum pragma_state
*** 43,46 ****
  extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *));
  
  /* Handle a C style pragma */
! extern void handle_pragma_token PROTO((char *, tree));
--- 45,50 ----
  extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *));
  
  /* Handle a C style pragma */
! extern int handle_pragma_token PROTO((char *, tree));
! 
! #endif /* HANDLE_SYSV_PRAGMA */

Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.37
diff -p -w -r1.37 varasm.c
*** varasm.c	1998/07/06 22:40:02	1.37
--- varasm.c	1998/08/15 00:06:24
*************** output_constructor (exp, size)
*** 4242,4247 ****
--- 4242,4248 ----
      assemble_zeros (size - total_bytes);
  }
  
+ #ifdef HANDLE_PRAGMA_WEAK
  /* Output asm to handle ``#pragma weak'' */
  
  void
*************** handle_pragma_weak (what, name, value)
*** 4249,4255 ****
       enum pragma_state what;
       char *name, *value;
  {
- #ifdef HANDLE_PRAGMA_WEAK
    if (what == ps_name || what == ps_value)
      {
        struct weak_syms *weak =
--- 4250,4255 ----
*************** handle_pragma_weak (what, name, value)
*** 4271,4278 ****
      }
    else if (! (what == ps_done || what == ps_start))
      warning ("malformed `#pragma weak'");
- #endif /* HANDLE_PRAGMA_WEAK */
  }
  
  /* Declare DECL to be a weak symbol.  */
  
--- 4271,4278 ----
      }
    else if (! (what == ps_done || what == ps_start))
      warning ("malformed `#pragma weak'");
  }
+ #endif /* HANDLE_PRAGMA_WEAK */
  
  /* Declare DECL to be a weak symbol.  */
  
Index: tm.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tm.texi,v
retrieving revision 1.43
diff -p -w -r1.43 tm.texi
*** tm.texi	1998/07/13 17:20:29	1.43
--- tm.texi	1998/08/15 00:02:27
*************** C++, which is to pretend that the file's
*** 7313,7322 ****
  @findex pragma
  @item HANDLE_PRAGMA (@var{stream}, @var{node})
  Define this macro if you want to implement any pragmas.  If defined, it
! is a C expression whose value is 1 if the pragma was handled by the function.
! The argument @var{stream} is the stdio input stream from which the source text
! can be read.  @var{node} is the tree node for the identifier after the
! @code{#pragma}.
  
  It is generally a bad idea to implement new uses of @code{#pragma}.  The
  only reason to define this macro is for compatibility with other
--- 7313,7329 ----
  @findex pragma
  @item HANDLE_PRAGMA (@var{stream}, @var{node})
  Define this macro if you want to implement any pragmas.  If defined, it
! is a C expression whose value is 1 if the pragma was handled by the
! function.  The argument @var{stream} varies depending upon whether
! USE_CPPLIB is define.  If it is not defined then @var{stream} is the
! stdio input stream from which the source text can be read.  @var{node}
! is the tree node for the identifier after the @code{#pragma}.  If it is
! defined, then @var{stream} will be a pointer to a function that can be
! used to retrieve characters from the input stream (if passed an argument
! of value -2), or to push characterts back into the input stream if
! passed any other value.  If the pragma is not handled, the input stream
! must be left in the same state as it was before HANDLE_PRAGMA was
! called. 
  
  It is generally a bad idea to implement new uses of @code{#pragma}.  The
  only reason to define this macro is for compatibility with other
*************** of @var{olddecl}.  Examples of when this
*** 7363,7372 ****
--- 7370,7395 ----
  overrides another, or when an attribute is nullified by a subsequent
  definition.
  
+ @findex INSERT_ATTRIBUTES
+ @item INSERT_ATTRIBUTES (@var{node}, @var{attr_ptr}, @var{prefix_ptr})
+ Define this macro if you want to be able to add attributes to a decl
+ when it is being created.  This is normally useful for backends which
+ wish to implement a pragma by using the attributes which correspond to
+ the pragma's effect.  The @var{node} argument is the decl which is being
+ created.  The @var{attr_ptr} argument is a pointer to the attribute list
+ for this decl.  The @var{prefix_ptr} is a pointer to the list of
+ attributes that have appeared after the specifiers and modifiers of the
+ declaration, but before the declaration proper.
+ 
  @findex SET_DEFAULT_DECL_ATTRIBUTES
  @item SET_DEFAULT_DECL_ATTRIBUTES (@var{decl}, @var{attributes})
  If defined, a C statement that assigns default attributes to
  newly defined @var{decl}.
+ 
+ @findex SET_DEFAULT_SECTION_NAME
+ @item SET_DEFAULT_SECTION_NAME (@var[decl})
+ If defined, a C statement that assigns a section name to the newly
+ created @var{decl}.
  
  @findex DOLLARS_IN_IDENTIFIERS
  @item DOLLARS_IN_IDENTIFIERS


Fri Aug 14 17:25:29 1998  Nick Clifton  <nickc@cygnus.com>

	* lex.c (check_newline):  Call HANDLE_PRAGMA before
	HANDLE_SYSV_PRAGMA if both are defined.  Generate warning messages
	if unknown pragmas are encountered.
	(handle_sysv_pragma): Interpret return code from
	handle_pragma_token ().  Return success/failure indication rather
	than next unprocessed character. 
	(get_ungetc): New function: retrieves or restores characters
	to/from the input stream.  Defined when HANDLE_PRAGMA and
	USE_CPPLIB are defined.

Index: cp/lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.61
diff -p -w -r1.61 lex.c
*** lex.c	1998/08/06 16:56:40	1.61
--- lex.c	1998/08/15 00:50:52
*************** get_last_nonwhite_on_line ()
*** 2212,2217 ****
--- 2212,2231 ----
    return c;
  }
  
+ #if defined HANDLE_PRAGMA && defined USE_CPPLIB
+ /* If passed an argument of -2 retrieve a character from the input stream.
+    If passed any other value (including EOF), stuff that value back into the
+    input stream.  */
+ int get_ungetc (arg)
+      int arg;
+ {
+   if (arg == -2)
+     return getch ();
+   else
+     put_back (arg);
+ }
+ #endif
+ 
  /* At the beginning of a line, increment the line number
     and process any #-directive on this line.
     If the line is a #-directive, read the entire line and return a newline.
*************** check_newline ()
*** 2278,2297 ****
  	      else if (token == END_OF_LINE)
  		goto skipline;
  
- #ifdef HANDLE_SYSV_PRAGMA
- 	      if (handle_sysv_pragma (token))
- 		goto skipline;
- #else
  #ifdef HANDLE_PRAGMA
! #if USE_CPPLIB
!               /* TODO: ??? */
                goto skipline;
  #else
    	      if (HANDLE_PRAGMA (finput, yylval.ttype))
    		goto skipline;
- #endif /* !USE_CPPLIB */
  #endif
! #endif
  	    }
  	  goto skipline;
  	}
--- 2292,2323 ----
  	      else if (token == END_OF_LINE)
  		goto skipline;
  
  #ifdef HANDLE_PRAGMA
! 	      /* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA
! 		 (if both are defined), in order to give the back
! 		 end a chance to override the interpretation of
! 		 SYSV style pragmas.  */
! #ifdef USE_CPPLIB	      
! 	      if (HANDLE_PRAGMA (get_ungetc, yylval.ttype))
  		goto skipline;
  #else	      
  	      if (HANDLE_PRAGMA (finput, yylval.ttype))
  		goto skipline;
  #endif
! #endif /* HANDLE_PRAGMA */
! 	      
! #ifdef HANDLE_SYSV_PRAGMA
! 	      if (handle_sysv_pragma (token))
! 		goto skipline;
! #endif /* !HANDLE_SYSV_PRAGMA */
! 
! 	      /* Issue a warning message if we have been asked to do so.
! 		 Ignoring unknown pragmas in system header file unless
! 		 an explcit -Wunknown-pragmas has been given. */
! 	      if (warn_unknown_pragmas > 1
! 		  || (warn_unknown_pragmas && ! in_system_header))
! 		warning ("ignoring pragma: %s", token_buffer);
! 	      
  	    }
  	  goto skipline;
  	}
*************** handle_sysv_pragma (token)
*** 4901,4907 ****
  	case TYPENAME:
  	case STRING:
  	case CONSTANT:
! 	  handle_pragma_token ("ignored", yylval.ttype);
  	  break;
  	case '(':
  	  handle_pragma_token ("(", NULL_TREE);
--- 4927,4933 ----
  	case TYPENAME:
  	case STRING:
  	case CONSTANT:
! 	  handle_pragma_token (IDENTIFIER_POINTER(yylval.ttype), yylval.ttype);
  	  break;
  	case '(':
  	  handle_pragma_token ("(", NULL_TREE);
*************** handle_sysv_pragma (token)
*** 4921,4928 ****
  	  break;
  	case END_OF_LINE:
  	default:
! 	  handle_pragma_token (NULL_PTR, NULL_TREE);
! 	  return 1;
  	}
        token = real_yylex ();
      }
--- 4947,4953 ----
  	  break;
  	case END_OF_LINE:
  	default:
! 	  return handle_pragma_token (NULL_PTR, NULL_TREE);
  	}
        token = real_yylex ();
      }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]