This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Improved HANDLE_PRAGMA macro and new INSERT_ATTRIBUTES macro
- To: egcs-patches at cygnus dot com
- Subject: Improved HANDLE_PRAGMA macro and new INSERT_ATTRIBUTES macro
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Fri, 14 Aug 1998 17:59:43 -0700
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 ();
}