This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Support for parsing some GHS pragmas
- To: egcs-patches at cygnus dot com
- Subject: Support for parsing some GHS pragmas
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Fri, 31 Jul 1998 11:20:03 -0700
Hi,
I would to submit the following patch. It adds support to EGCS for
parsing a few GHS pragmas, which is useful for the v850 port.
Cheers
Nick
Fri Jul 31 09:45:07 1998 Nick Clifton <nickc@cygnus.com>
* c-pragma.c: Add support for parsing some GHS pragmas.
* c-pragma.h: ditto.
* c-decl.c: ditto.
* c-common.c: ditto.
* c-lex.c: ditto.
* tree.h: ditto.
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/07/31 18:12:54
***************
*** 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. */
*** 29,35 ****
#include "flags.h"
#include "toplev.h"
! #ifdef HANDLE_SYSV_PRAGMA
/* When structure field packing is in effect, this variable is the
number of bits to use as the maximum alignment. When packing is not
--- 29,35 ----
#include "flags.h"
#include "toplev.h"
! #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
/* When structure field packing is in effect, this variable is the
number of bits to use as the maximum alignment. When packing is not
*************** extern int maximum_field_alignment;
*** 40,45 ****
--- 40,231 ----
/* File used for outputting assembler code. */
extern FILE *asm_out_file;
+ /* Tracks the current data area set by the data area pragma (which
+ can be nested). Tested by check_default_data_area. */
+
+ typedef struct data_area_stack_element
+ {
+ struct data_area_stack_element * prev;
+ enum DATA_AREA data_area; /* current default data area. */
+ char * data_area_name; /* name of default data area. */
+ } data_area_stack_element;
+
+ static data_area_stack_element * data_area_stack = NULL;
+
+ /* Add data area to the given declaration if a ghs data area pragma is
+ currently in effect (#pragma ghs startXXX/endXXX). Also output attr
+ file entry if requested.
+ */
+ void
+ check_default_data_area (decl)
+ tree decl;
+ {
+ #ifdef HANDLE_GHS_PRAGMA
+ if (data_area_stack
+ && data_area_stack->data_area
+ && current_function_decl == NULL_TREE
+ && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL)
+ && ! DECL_DATA_AREA (decl))
+ {
+ DECL_DATA_AREA (decl) = data_area_stack->data_area;
+ }
+ #endif /* HANDLE_GHS_PRAGMA */
+ }
+
+ #ifdef HANDLE_GHS_PRAGMA
+ /* enum GHS_SECTION_KIND is an enumeration of the kinds of sections that
+ can appear in the "ghs section" pragma. These names are used to index
+ into the two arrays that follow it (and so the ordering of each must
+ remain consistant).
+
+ These arrays give the default and current names for each kind of
+ section defined by the GHS pragmas. The current names can be changed
+ by the "ghs section" pragma. If the current names are null, use
+ the default names. Note that the two arrays have different types.
+
+ For the *normal* section kinds (like .data, .text, etc.) we do not
+ want to explicitly force the name of these sections, but would rather
+ let the linker (or at least the back end) choose the name of the
+ section, UNLESS the user has force a specific name for these section
+ kinds. To accomplish this set the name in ghs_default_section_names
+ to null. */
+
+ enum GHS_SECTION_KIND
+ {
+ GHS_SECTION_KIND_DUMMY,
+
+ GHS_SECTION_KIND_TEXT,
+ GHS_SECTION_KIND_DATA,
+ GHS_SECTION_KIND_RODATA,
+ GHS_SECTION_KIND_BSS,
+
+ #ifdef HAVE_SDA
+ GHS_SECTION_KIND_SDATA,
+ GHS_SECTION_KIND_ROSDATA,
+ #endif
+
+ #ifdef HAVE_TDA
+ GHS_SECTION_KIND_TDATA,
+ #endif
+
+ #ifdef HAVE_ZDA
+ GHS_SECTION_KIND_ZDATA,
+ GHS_SECTION_KIND_ROZDATA,
+ #endif
+
+ COUNT_OF_GHS_SECTION_KINDS /* must be last */
+ };
+
+ static tree ghs_default_section_names[ (int)COUNT_OF_GHS_SECTION_KINDS ];
+ static tree ghs_current_section_names[ (int)COUNT_OF_GHS_SECTION_KINDS ];
+
+ #endif /* HANDLE_GHS_PRAGMA */
+
+ /* Add a section name to the given declaration if necessary.
+ Also output attr file entry if requested. */
+ void
+ check_default_section_name (decl)
+ tree decl;
+ {
+ #ifdef HANDLE_GHS_PRAGMA
+ #ifdef HAVE_SDA
+ if (!ghs_default_section_names[ (int)GHS_SECTION_KIND_SDATA ])
+ {
+ ghs_default_section_names[ (int)GHS_SECTION_KIND_SDATA ]
+ = build_string (sizeof (".sdata")-1, ".sdata");
+
+ ghs_default_section_names[ (int)GHS_SECTION_KIND_ROSDATA ]
+ = build_string (sizeof (".rosdata")-1, ".rosdata");
+ }
+ #endif
+ #ifdef HAVE_ZDA
+ if (!ghs_default_section_names[ (int)GHS_SECTION_KIND_ZDATA ])
+ {
+ ghs_default_section_names[ (int)GHS_SECTION_KIND_ZDATA ]
+ = build_string (sizeof (".zdata")-1, ".zdata");
+
+ ghs_default_section_names[ (int)GHS_SECTION_KIND_ROZDATA ]
+ = build_string (sizeof (".rozdata")-1, ".rozdata");
+ }
+ #endif
+ #ifdef HAVE_TDA
+ if (!ghs_default_section_names[ (int)GHS_SECTION_KIND_TDATA ])
+ ghs_default_section_names[ (int)GHS_SECTION_KIND_TDATA ]
+ = build_string (sizeof (".tdata")-1, ".tdata");
+ #endif
+
+ if (current_function_decl == NULL_TREE
+ && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL || TREE_CODE (decl) == FUNCTION_DECL)
+ && (!DECL_EXTERNAL (decl) || DECL_INITIAL (decl))
+ && !DECL_SECTION_NAME (decl))
+ {
+ enum GHS_SECTION_KIND kind = GHS_SECTION_KIND_DUMMY;
+ tree choosen_section = 0;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ kind = GHS_SECTION_KIND_TEXT;
+ else
+ {
+ /* First choose a section kind based on the attributes of the decl. */
+ switch (DECL_DATA_AREA (decl))
+ {
+ default:
+ abort ();
+
+ #ifdef HAVE_SDA
+ case DATA_AREA_SDA:
+ kind = ((TREE_READONLY (decl))
+ ? GHS_SECTION_KIND_ROSDATA
+ : GHS_SECTION_KIND_SDATA);
+ break;
+ #endif
+
+ #ifdef HAVE_TDA
+ case DATA_AREA_TDA:
+ kind = GHS_SECTION_KIND_TDATA;
+ break;
+ #endif
+
+ #ifdef HAVE_ZDA
+ case DATA_AREA_ZDA:
+ kind = ((TREE_READONLY (decl))
+ ? GHS_SECTION_KIND_ROZDATA
+ : GHS_SECTION_KIND_ZDATA);
+ break;
+ #endif
+
+ case DATA_AREA_NONE: /* default data area */
+
+ if (TREE_READONLY (decl))
+ kind = GHS_SECTION_KIND_RODATA;
+ else if (DECL_INITIAL (decl))
+ kind = GHS_SECTION_KIND_DATA;
+ else
+ kind = GHS_SECTION_KIND_BSS;
+ }
+ }
+
+ /* Now, if the section kind has been explicitly renamed,
+ then attach a section attribute. */
+ if (ghs_current_section_names[ (int)kind ])
+ {
+ choosen_section = ghs_current_section_names[ (int)kind ];
+
+ /* Only set the section name if this is a pragma, because otherwise
+ it will force those variables to get allocated storage in this
+ module, rather than by the linker. */
+ DECL_SECTION_NAME (decl) = choosen_section;
+ }
+
+ /* Otherwise, if this kind of section needs an explicit section
+ attribute, then also attach one. */
+ else if (ghs_default_section_names[ (int)kind ])
+ choosen_section = ghs_default_section_names[ (int)kind ];
+ }
+
+ #endif /* HANDLE_GHS_PRAGMA */
+ }
+
/* Handle one token of a pragma directive. TOKEN is the
current token, and STRING is its printable form. */
*************** handle_pragma_token (string, token)
*** 53,59 ****
static char *value;
static int align;
! if (string == 0)
{
if (type == ps_pack)
{
--- 239,251 ----
static char *value;
static int align;
! static enum DATA_AREA data_area;
! static char * data_area_name;
! #ifdef HANDLE_GHS_PRAGMA
! static enum GHS_SECTION_KIND ghs_section_kind;
! #endif
!
! if (string == NULL)
{
if (type == ps_pack)
{
*************** handle_pragma_token (string, token)
*** 67,76 ****
#ifdef HANDLE_PRAGMA_WEAK
if (HANDLE_PRAGMA_WEAK)
handle_pragma_weak (state, name, value);
-
#endif /* HANDLE_PRAGMA_WEAK */
}
type = state = ps_start;
return;
}
--- 259,318 ----
#ifdef HANDLE_PRAGMA_WEAK
if (HANDLE_PRAGMA_WEAK)
handle_pragma_weak (state, name, value);
#endif /* HANDLE_PRAGMA_WEAK */
}
+ #ifdef HANDLE_GHS_PRAGMA
+ else if (type == ps_ghspragma_interrupt)
+ mark_current_function_as_interrupt ();
+
+ else if (type == ps_ghspragma_startsection)
+ {
+ data_area_stack_element* elem
+ = (data_area_stack_element*)xmalloc (sizeof(*elem));
+ elem->prev = data_area_stack;
+ elem->data_area = data_area;
+ elem->data_area_name = data_area_name;
+ data_area_stack = elem;
+ }
+
+ else if (type == ps_ghspragma_endsection)
+ {
+ if (data_area_stack == NULL)
+ warning ("#pragma ghs endXXX found without previous startXXX");
+
+ else if (data_area != data_area_stack->data_area)
+ warning ("#pragma ghs endXXX does not match previous startXXX");
+ else
+ {
+ data_area_stack_element* dead = data_area_stack;
+ data_area_stack = data_area_stack->prev;
+ free (dead);
+ }
+ }
+
+ else if (type == ps_ghspragma_section)
+ {
+ /* For each ghs section kind, set it back to it's default name */
+ int i;
+ for (i=0; i<COUNT_OF_GHS_SECTION_KINDS; i++)
+ ghs_current_section_names[i] = 0;
+ }
+
+ else if (type == ps_ghspragma_section_kind)
+ {
+ if (state == ps_ghspragma_section_mightend)
+ {
+ /* The work for this type pragma is already done. */
+ }
+ else
+ warning ("incomplete #pragma ghs section");
+ }
+
+ else if (type == ps_ghspragma)
+ warning ("incomplete #pragma ghs");
+ #endif /* HANDLE_GHS_PRAGMA */
+
type = state = ps_start;
return;
}
*************** handle_pragma_token (string, token)
*** 84,89 ****
--- 326,339 ----
type = state = ps_pack;
else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
type = state = ps_weak;
+ #ifdef HANDLE_GHS_PRAGMA
+ else if (strcmp (IDENTIFIER_POINTER (token), "ghs") == 0)
+ {
+ type = state = ps_ghspragma;
+ data_area = 0;
+ data_area_name = NULL;
+ }
+ #endif /* HANDLE_GHS_PRAGMA */
else
{
type = state = ps_done;
*************** handle_pragma_token (string, token)
*** 170,175 ****
--- 420,654 ----
state = ps_bad;
break;
+ #ifdef HANDLE_GHS_PRAGMA
+ case ps_ghspragma:
+ if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+ {
+ if (strcmp (IDENTIFIER_POINTER (token), "interrupt") == 0)
+ {
+ type = ps_ghspragma_interrupt;
+ state = ps_should_be_done;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "section") == 0)
+ {
+ type = state = ps_ghspragma_section;
+ }
+
+ #ifdef HAVE_TDA
+ else if (strcmp (IDENTIFIER_POINTER (token), "starttda") == 0)
+ {
+ type = ps_ghspragma_startsection;
+ data_area = DATA_AREA_TDA;
+ data_area_name = "tda";
+ state = ps_should_be_done;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "endtda") == 0)
+ {
+ type = ps_ghspragma_endsection;
+ data_area = DATA_AREA_TDA;
+ data_area_name = "tda";
+ state = ps_should_be_done;
+ }
+ #endif /* HAVE_TDA */
+
+ #ifdef HAVE_SDA
+ else if (strcmp (IDENTIFIER_POINTER (token), "startsda") == 0)
+ {
+ type = ps_ghspragma_startsection;
+ data_area = DATA_AREA_SDA;
+ data_area_name = "sda";
+ state = ps_should_be_done;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "endsda") == 0)
+ {
+ type = ps_ghspragma_endsection;
+ data_area = DATA_AREA_SDA;
+ data_area_name = "sda";
+ state = ps_should_be_done;
+ }
+ #endif /* HAVE_SDA */
+
+ #ifdef HAVE_ZDA
+ else if (strcmp (IDENTIFIER_POINTER (token), "startzda") == 0)
+ {
+ type = ps_ghspragma_startsection;
+ data_area = DATA_AREA_ZDA;
+ data_area_name = "zda";
+ state = ps_should_be_done;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "endzda") == 0)
+ {
+ type = ps_ghspragma_endsection;
+ data_area = DATA_AREA_ZDA;
+ data_area_name = "zda";
+ state = ps_should_be_done;
+ }
+ #endif /* HAVE_ZDA */
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "startdata") == 0)
+ {
+ type = ps_ghspragma_startsection;
+ data_area = 0;
+ data_area_name = 0;
+ state = ps_should_be_done;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "enddata") == 0)
+ {
+ type = ps_ghspragma_endsection;
+ data_area = 0;
+ data_area_name = 0;
+ state = ps_should_be_done;
+ }
+
+ else
+ {
+ warning ("Ignoring GHS pragma: %s\n", IDENTIFIER_POINTER (token) );
+
+ /* Ignore 'ghs' pragmas we don't understand. */
+ type = state = ps_bad;
+ }
+ }
+ else
+ {
+ /* Ignore 'ghs' pragmas we don't understand. */
+ type = state = ps_bad;
+ }
+ break;
+
+ case ps_ghspragma_section:
+ if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+ {
+ if (strcmp (IDENTIFIER_POINTER (token), "data") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_DATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "sdata") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_SDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "rodata") == 0
+ || strcmp (IDENTIFIER_POINTER (token), "const") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_RODATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "rosdata") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_ROSDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "rozdata") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_ROZDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "tdata") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_TDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "zdata") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_ZDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "bss") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_BSS;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "zbss") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_ZDATA;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else if (strcmp (IDENTIFIER_POINTER (token), "text") == 0)
+ {
+ ghs_section_kind = GHS_SECTION_KIND_TEXT;
+ type = state = ps_ghspragma_section_kind;
+ }
+
+ else
+ {
+ warning ("unknown section kind in ghs section pragma: %s",
+ IDENTIFIER_POINTER (token) );
+ type = state = ps_bad;
+ }
+ }
+ else
+ {
+ warning ("unknown section kind in ghs section pragma: %s",
+ IDENTIFIER_POINTER (token) );
+ type = state = ps_bad;
+ }
+ break;
+
+ case ps_ghspragma_section_kind:
+ if (0 == strcmp (string, "="))
+ {
+ state = ps_ghspragma_section_kind_equals;
+ }
+ else
+ {
+ warning ("malformed ghs section pragma");
+ type = state = ps_bad;
+ }
+ break;
+
+ case ps_ghspragma_section_kind_equals:
+ if (0 == strcmp (string, "default"))
+ {
+ /* Set the current name for the 'ghs_section_kind' to its default. */
+ ghs_current_section_names[ghs_section_kind] = 0;
+ state = ps_ghspragma_section_mightend;
+ }
+ else if (token && TREE_CODE (token) == STRING_CST)
+ {
+ /* Set the current name for the 'ghs_section_kind' to token. */
+ ghs_current_section_names[ghs_section_kind] = token;
+ state = ps_ghspragma_section_mightend;
+ }
+ else
+ {
+ warning ("malformed ghs section pragma");
+ type = state = ps_bad;
+ }
+ break;
+
+ case ps_ghspragma_section_mightend:
+ if (0 == strcmp (string, ","))
+ {
+ state = ps_ghspragma_section;
+ }
+ else
+ {
+ warning ("malformed ghs section pragma");
+ type = state = ps_bad;
+ }
+ break;
+
+ case ps_should_be_done:
+ warning ("extra tokens after valid #pragma");
+ state = ps_bad;
+ break;
+ #endif /* HANDLE_GHS_PRAGMA */
+
case ps_bad:
case ps_done:
break;
*************** handle_pragma_token (string, token)
*** 178,181 ****
abort ();
}
}
! #endif /* HANDLE_SYSV_PRAGMA */
--- 657,660 ----
abort ();
}
}
! #endif /* HANDLE_SYSV_PRAGMA || HANDLE_GHS_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/07/31 18:13:26
***************
*** 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.
*************** enum pragma_state
*** 37,42 ****
--- 37,56 ----
ps_left,
ps_align,
ps_right
+ #ifdef HANDLE_GHS_PRAGMA
+ ,
+ ps_ghspragma,
+ ps_ghspragma_interrupt,
+ ps_ghspragma_startsection,
+ ps_ghspragma_endsection,
+
+ ps_ghspragma_section,
+ ps_ghspragma_section_kind,
+ ps_ghspragma_section_kind_equals,
+ ps_ghspragma_section_mightend,
+
+ ps_should_be_done
+ #endif /* HANDLE_GHS_PRAGMA */
};
/* Output asm to handle ``#pragma weak'' */
Index: c-decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-decl.c,v
retrieving revision 1.40
diff -p -w -r1.40 c-decl.c
*** c-decl.c 1998/07/30 10:38:08 1.40
--- c-decl.c 1998/07/31 18:13:59
*************** duplicate_decls (newdecl, olddecl, diffe
*** 1462,1467 ****
--- 1462,1473 ----
DECL_MACHINE_ATTRIBUTES (newdecl)
= merge_machine_decl_attributes (olddecl, newdecl);
+ if (TREE_CODE (olddecl) == VAR_DECL
+ && TREE_CODE (newdecl) == VAR_DECL
+ && DECL_DATA_AREA (olddecl) != 0
+ && DECL_DATA_AREA (newdecl) == 0)
+ DECL_DATA_AREA (newdecl) = DECL_DATA_AREA (olddecl);
+
if (TREE_CODE (newtype) == ERROR_MARK
|| TREE_CODE (oldtype) == ERROR_MARK)
types_match = 0;
*************** start_decl (declarator, declspecs, initi
*** 3824,3829 ****
--- 3830,3843 ----
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (decl, attributes, prefix_attributes);
+ #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
+ /* Check for a default data area */
+ check_default_data_area (decl);
+
+ /* Check for a pragma specified section name */
+ check_default_section_name (decl);
+ #endif
+
/* Add this decl to the current binding level.
TEM may equal DECL or it may be a previous decl of the same name. */
tem = pushdecl (decl);
*************** start_function (declspecs, declarator, p
*** 6430,6435 ****
--- 6444,6454 ----
except for defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL (decl1) = current_extern_inline;
+ #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
+ /* Check for a pragma specified section name */
+ check_default_section_name (decl1);
+ #endif
+
/* This function exists in static storage.
(This does not mean `static' in the C sense!) */
TREE_STATIC (decl1) = 1;
Index: c-common.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-common.c,v
retrieving revision 1.27
diff -p -w -r1.27 c-common.c
*** c-common.c 1998/07/30 10:38:07 1.27
--- c-common.c 1998/07/31 18:14:43
*************** int skip_evaluation;
*** 52,58 ****
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
! A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
enum format_type { printf_format_type, scanf_format_type,
strftime_format_type };
--- 52,60 ----
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
! A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS,
! A_SDA, A_TDA, A_ZDA
! };
enum format_type { printf_format_type, scanf_format_type,
strftime_format_type };
*************** static void init_attributes PROTO((void
*** 64,69 ****
--- 66,72 ----
static void record_function_format PROTO((tree, tree, enum format_type,
int, int));
static void record_international_format PROTO((tree, tree, int));
+ static void mark_function_as_interrupt PROTO((tree));
/* Keep a stack of if statements. We record the number of compound
statements seen up to the if keyword, as well as the line number
*************** init_attributes ()
*** 384,389 ****
--- 387,395 ----
add_attribute (A_WEAK, "weak", 0, 0, 1);
add_attribute (A_ALIAS, "alias", 1, 1, 1);
add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1);
+ add_attribute (A_SDA, "sda", 0, 0, 1);
+ add_attribute (A_TDA, "tda", 0, 0, 1);
+ add_attribute (A_ZDA, "zda", 0, 0, 1);
}
/* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
*************** decl_attributes (node, attributes, prefi
*** 875,882 ****
--- 881,939 ----
else
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
break;
+
+ case A_SDA:
+ case A_TDA:
+ case A_ZDA:
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL)
+ {
+ if (TREE_CODE (decl) == VAR_DECL
+ && current_function_decl != NULL_TREE)
+ error_with_decl (decl,
+ "a data area attribute cannot be specified for local variables");
+
+ else if (DECL_DATA_AREA (decl) != 0)
+ {
+ if ((id == A_SDA && DECL_DATA_AREA (decl) != DATA_AREA_SDA)
+ || (id == A_TDA && DECL_DATA_AREA (decl) != DATA_AREA_TDA)
+ || (id == A_ZDA && DECL_DATA_AREA (decl) != DATA_AREA_ZDA))
+ error_with_decl (node,
+ "data area of `%s' conflicts with previous declaration");
+ }
+
+ else
+ {
+ if (id == A_SDA)
+ DECL_DATA_AREA (decl) = DATA_AREA_SDA;
+ else if (id == A_TDA)
+ DECL_DATA_AREA (decl) = DATA_AREA_TDA;
+ else if (id == A_ZDA)
+ DECL_DATA_AREA (decl) = DATA_AREA_ZDA;
+ }
}
+
+ else
+ error_with_decl (node,
+ "data area attribute not allowed for `%s'");
+ break;
+ }
+ }
+ }
+
+ /* Here we must do whatever's needed for making an interrupt function.
+ I'm not at all sure what that would be. */
+
+ static void
+ mark_function_as_interrupt (decl)
+ tree decl;
+ {
}
+
+ void
+ mark_current_function_as_interrupt()
+ {
+ mark_function_as_interrupt (current_function_decl);
}
/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
Index: c-lex.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/c-lex.c,v
retrieving revision 1.61
diff -w -p -r1.61 c-lex.c
*** c-lex.c 1998/07/27 19:32:35 1.61
--- c-lex.c 1998/07/31 17:00:31
*************** static int end_of_file;
*** 114,122 ****
static int nextchar = -1;
#endif
! #ifdef HANDLE_SYSV_PRAGMA
static int handle_sysv_pragma PROTO((int));
#endif /* HANDLE_SYSV_PRAGMA */
static int whitespace_cr PROTO((int));
static int skip_white_space PROTO((int));
static int skip_white_space_on_line PROTO((void));
--- 114,124 ----
static int nextchar = -1;
#endif
! /* CYGNUS LOCAL nickc/ghs */
! #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
static int handle_sysv_pragma PROTO((int));
#endif /* HANDLE_SYSV_PRAGMA */
+ /* END CYGNUS LOCAL */
static int whitespace_cr PROTO((int));
static int skip_white_space PROTO((int));
static int skip_white_space_on_line PROTO((void));
*************** check_newline ()
*** 530,542 ****
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);
--- 532,544 ----
c = GETC ();
if (c == '\n')
return c;
! #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
UNGETC (c);
token = yylex ();
if (token != IDENTIFIER)
goto skipline;
return handle_sysv_pragma (token);
! #else /* !HANDLE_SYSV_PRAGMA && ! HANDLE_GHS_PRAGMA */
#ifdef HANDLE_PRAGMA
#if !USE_CPPLIB
UNGETC (c);
*************** check_newline ()
*** 557,563 ****
??? do not know what to do ???;
#endif /* !USE_CPPLIB */
#endif /* HANDLE_PRAGMA */
! #endif /* !HANDLE_SYSV_PRAGMA */
goto skipline;
}
}
--- 559,565 ----
??? do not know what to do ???;
#endif /* !USE_CPPLIB */
#endif /* HANDLE_PRAGMA */
! #endif /* !HANDLE_SYSV_PRAGMA && ! HANDLE_GHS_PRAGMA */
goto skipline;
}
}
*************** linenum:
*** 816,822 ****
return c;
}
! #ifdef HANDLE_SYSV_PRAGMA
/* Handle a #pragma directive.
TOKEN is the token we read after `#pragma'. Processes the entire input
--- 818,824 ----
return c;
}
! #if defined HANDLE_SYSV_PRAGMA || defined HANDLE_GHS_PRAGMA
/* Handle a #pragma directive.
TOKEN is the token we read after `#pragma'. Processes the entire input
*************** handle_sysv_pragma (token)
*** 863,869 ****
}
}
! #endif /* HANDLE_SYSV_PRAGMA */
#define ENDFILE -1 /* token that represents end-of-file */
--- 865,871 ----
}
}
! #endif /* HANDLE_SYSV_PRAGMA || HANDLE_GHS_PRAGMA */
#define ENDFILE -1 /* token that represents end-of-file */
Index: tree.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/tree.h,v
retrieving revision 1.162
diff -w -p -r1.162 tree.h
*** tree.h 1998/07/30 17:38:14 1.162
--- tree.h 1998/07/31 17:00:44
*************** struct tree_type
*** 991,1000 ****
/* Records the section name in a section attribute. Used to pass
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
#define DECL_SECTION_NAME(NODE) (DECL_CHECK (NODE)->decl.section_name)
! /* start-sanitize-depragmaize */
/* Record the data area attribute. */
#define DECL_DATA_AREA(NODE) ((NODE)->decl.data_area)
! /* end-sanitize-depragmaize */
/* For FIELD_DECLs, this is the
RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is
a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
--- 991,1000 ----
/* Records the section name in a section attribute. Used to pass
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
#define DECL_SECTION_NAME(NODE) (DECL_CHECK (NODE)->decl.section_name)
! /* CYGNUS LOCAL nickc/ghs */
/* Record the data area attribute. */
#define DECL_DATA_AREA(NODE) ((NODE)->decl.data_area)
! /* END CYGNUS LOCAL */
/* For FIELD_DECLs, this is the
RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is
a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
*************** struct tree_decl
*** 1296,1309 ****
union tree_node *vindex;
/* Points to a structure whose details depend on the language in use. */
struct lang_decl *lang_specific;
! /* start-sanitize-depragmaize */
! enum DATA_AREA {
DATA_AREA_NONE = 0,
DATA_AREA_SDA,
DATA_AREA_TDA,
DATA_AREA_ZDA
} data_area;
! /* end-sanitize-depragmaize */
};
/* Define the overall contents of a tree node.
--- 1296,1310 ----
union tree_node *vindex;
/* Points to a structure whose details depend on the language in use. */
struct lang_decl *lang_specific;
! /* CYGNUS LOCAL nickc/ghs */
! enum DATA_AREA
! {
DATA_AREA_NONE = 0,
DATA_AREA_SDA,
DATA_AREA_TDA,
DATA_AREA_ZDA
} data_area;
! /* END CYGNUS LOCAL */
};
/* Define the overall contents of a tree node.