From: Zack Weinberg Date: Thu, 7 Sep 2000 22:24:34 +0000 (+0000) Subject: c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if REGISTER_TARGET_PRAGMAS is defined. X-Git-Tag: prereleases/libstdc++-2.92~4178 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=8b97c5f8ef218afce7499abe8cd3e6eb1f729306;p=gcc.git c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if REGISTER_TARGET_PRAGMAS is defined. * c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if REGISTER_TARGET_PRAGMAS is defined. Duplicate some definitions from cpplib.h. * cpplib.h: Don't typedef struct cpp_reader if c-pragma.h has already done it. * tm.texi: Document HANDLE_PRAGMA as no longer supported. Add documentation for REGISTER_TARGET_PRAGMAS. * c-lex.c: Include cpplib.h before c-pragma.h. Define a default-pragma callback to implement -Wunknown-pragmas if USE_CPPLIB. * c-parse.in: Move all includes to top of file. * c-pragma.c: Include cpplib.h before c-pragma.h. Include tm_p.h. (dispatch_pragma): Put the namespace in the -Wunknown-pragmas warning. (init_pragma): If REGISTER_TARGET_PRAGMAS is defined, call it. * arm.h, arm-protos.h, arm.c, c4x.h, c4x-protos.h, c4x.c, h8300.h, h8300-protos.h, h8300.c, i370.h, i370-protos.h, i370.c, i960.h, i960-protos.h, i960.c, sh.h, sh-protos.h, sh.c, v850.h, v850-protos.h, v850.c: Convert HANDLE_PRAGMA-based pragmata scheme to use REGISTER_TARGET_PRAGMAS instead. * d30v.h: Don't mention HANDLE_PRAGMA in comment. Add multiple include guard. * i370.md (untyped_call): Use GEN_CALL. (umodsi3): Remove unused variable. * sh/elf.h: Don't undef HANDLE_SYSV_PRAGMA. * v850.c (output_move_single, output_move_double): Constify return value. (print_operand): Constify a char *. * v850.h (struct small_memory_info): Constify name member. From-SVN: r36249 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58ba77d5db95..628f6c78e9fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2000-09-07 Zack Weinberg + + * c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if + REGISTER_TARGET_PRAGMAS is defined. Duplicate some + definitions from cpplib.h. + * cpplib.h: Don't typedef struct cpp_reader if c-pragma.h has + already done it. + * tm.texi: Document HANDLE_PRAGMA as no longer supported. Add + documentation for REGISTER_TARGET_PRAGMAS. + + * c-lex.c: Include cpplib.h before c-pragma.h. Define a + default-pragma callback to implement -Wunknown-pragmas if + USE_CPPLIB. + * c-parse.in: Move all includes to top of file. + * c-pragma.c: Include cpplib.h before c-pragma.h. Include + tm_p.h. + (dispatch_pragma): Put the namespace in the -Wunknown-pragmas + warning. + (init_pragma): If REGISTER_TARGET_PRAGMAS is defined, call it. + + * arm.h, arm-protos.h, arm.c, + c4x.h, c4x-protos.h, c4x.c, + h8300.h, h8300-protos.h, h8300.c, + i370.h, i370-protos.h, i370.c, + i960.h, i960-protos.h, i960.c, + sh.h, sh-protos.h, sh.c, + v850.h, v850-protos.h, v850.c: Convert HANDLE_PRAGMA-based + pragmata scheme to use REGISTER_TARGET_PRAGMAS instead. + + * d30v.h: Don't mention HANDLE_PRAGMA in comment. Add + multiple include guard. + * i370.md (untyped_call): Use GEN_CALL. + (umodsi3): Remove unused variable. + * sh/elf.h: Don't undef HANDLE_SYSV_PRAGMA. + * v850.c (output_move_single, output_move_double): Constify + return value. + (print_operand): Constify a char *. + * v850.h (struct small_memory_info): Constify name member. + 2000-09-07 Kazu Hirata * config/h8300.h: Fix comment typos. diff --git a/gcc/c-lex.c b/gcc/c-lex.c index 84ef09499bca..63ae9ba66766 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ #include "c-tree.h" #include "flags.h" #include "timevar.h" +#include "cpplib.h" #include "c-pragma.h" #include "toplev.h" #include "intl.h" @@ -52,8 +53,6 @@ Boston, MA 02111-1307, USA. */ #define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ((ENV_VALUE) = getenv (ENV_NAME)) #endif -#include "cpplib.h" - #if USE_CPPLIB extern cpp_reader parse_in; #else @@ -162,6 +161,7 @@ static void cb_ident PARAMS ((cpp_reader *, const unsigned char *, static void cb_enter_file PARAMS ((cpp_reader *)); static void cb_leave_file PARAMS ((cpp_reader *)); static void cb_rename_file PARAMS ((cpp_reader *)); +static void cb_def_pragma PARAMS ((cpp_reader *)); #endif @@ -210,6 +210,7 @@ init_c_lex (filename) parse_in.cb.enter_file = cb_enter_file; parse_in.cb.leave_file = cb_leave_file; parse_in.cb.rename_file = cb_rename_file; + parse_in.cb.def_pragma = cb_def_pragma; /* Make sure parse_in.digraphs matches flag_digraphs. */ CPP_OPTION (&parse_in, digraphs) = flag_digraphs; @@ -777,6 +778,27 @@ cb_rename_file (pfile) /* Hook for C++. */ extract_interface_info (); } + +static void +cb_def_pragma (pfile) + cpp_reader *pfile; +{ + /* Issue a warning message if we have been asked to do so. Ignore + unknown pragmas in system headers unless an explicit + -Wunknown-pragmas has been given. */ + if (warn_unknown_pragmas > in_system_header) + { + const unsigned char *space, *name; + const cpp_token *t = pfile->first_directive_token + 2; + + space = t[0].val.node->name; + name = t[1].type == CPP_NAME ? t[1].val.node->name : 0; + if (name) + warning ("ignoring #pragma %s %s", space, name); + else + warning ("ignoring #pragma %s", space); + } +} #endif /* USE_CPPLIB */ /* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 9d2001bd5c7c..5ef738672f77 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -41,6 +41,9 @@ end ifc #include #include "tree.h" #include "input.h" +#include "cpplib.h" +#include "intl.h" +#include "timevar.h" #include "c-lex.h" #include "c-tree.h" #include "c-pragma.h" @@ -2797,9 +2800,6 @@ end ifobjc /* yylex() is a thin wrapper around c_lex(), all it does is translate cpplib.h's token codes into yacc's token codes. */ -#include "cpplib.h" -#include "intl.h" -#include "timevar.h" static enum cpp_ttype last_token; #if USE_CPPLIB diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index 2d6bee838745..820720d9706f 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -24,12 +24,13 @@ Boston, MA 02111-1307, USA. */ #include "tree.h" #include "function.h" #include "defaults.h" +#include "cpplib.h" #include "c-pragma.h" #include "flags.h" #include "toplev.h" #include "ggc.h" #include "c-lex.h" -#include "cpplib.h" +#include "tm_p.h" #ifdef HANDLE_GENERIC_PRAGMAS @@ -383,7 +384,7 @@ dispatch_pragma () enum cpp_ttype t; tree x; const struct pragma_entry *p; - const char *name; + const char *name, *space = 0; size_t len; p = pragmas; @@ -407,6 +408,7 @@ dispatch_pragma () { if (p->isnspace) { + space = p->name; p = p->u.space; goto new_space; } @@ -420,10 +422,15 @@ dispatch_pragma () } /* Issue a warning message if we have been asked to do so. Ignore - unknown pragmas in system header file unless an explcit + unknown pragmas in system headers unless an explicit -Wunknown-pragmas has been given. */ if (warn_unknown_pragmas > in_system_header) - warning ("ignoring pragma %s", name); + { + if (space) + warning ("ignoring #pragma %s %s", space, name); + else + warning ("ignoring #pragma %s", name); + } } #endif @@ -444,6 +451,10 @@ init_pragma () cpp_register_pragma (pfile, 0, "weak", handle_pragma_weak); #endif +#ifdef REGISTER_TARGET_PRAGMAS + REGISTER_TARGET_PRAGMAS (pfile); +#endif + #ifdef HANDLE_PRAGMA_PACK_PUSH_POP ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack), mark_align_stack); diff --git a/gcc/c-pragma.h b/gcc/c-pragma.h index 50d0f57ab7a5..d669d9d734fc 100644 --- a/gcc/c-pragma.h +++ b/gcc/c-pragma.h @@ -62,7 +62,8 @@ extern int add_weak PARAMS ((const char *, const char *)); parsing is to be done. The code in GCC's generic C source files will only look for the definition of this constant. They will ignore definitions of HANDLE_PRAGMA_PACK and so on. */ -#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK +#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK \ + || defined REGISTER_TARGET_PRAGMAS #define HANDLE_GENERIC_PRAGMAS #endif @@ -77,4 +78,15 @@ extern void dispatch_pragma PARAMS ((void)); # define init_pragma() #endif +/* Duplicate prototypes for the register_pragma stuff and the typedef for + cpp_reader, to avoid dragging cpplib.h in almost everywhere... */ +#ifndef __GCC_CPPLIB__ +typedef struct cpp_reader cpp_reader; + +extern void cpp_register_pragma PARAMS ((cpp_reader *, + const char *, const char *, + void (*) PARAMS ((cpp_reader *)))); +extern void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *)); +#endif + #endif /* _C_PRAGMA_H */ diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index ae2a7de30849..bc05fa76a97f 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -20,11 +20,12 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_ARM_PROTOS_H +#define GCC_ARM_PROTOS_H + extern void arm_override_options PARAMS ((void)); extern int use_return_insn PARAMS ((int)); extern int arm_regno_class PARAMS ((int)); -extern int arm_process_pragma PARAMS ((int (*)(void), void (*) (int), - char *)); extern void arm_finalize_pic PARAMS ((void)); extern int arm_volatile_func PARAMS ((void)); extern const char * arm_output_epilogue PARAMS ((int)); @@ -194,3 +195,11 @@ extern int arm_dllimport_p PARAMS ((tree)); extern void arm_mark_dllexport PARAMS ((tree)); extern void arm_mark_dllimport PARAMS ((tree)); #endif + +#ifdef _C_PRAGMA_H /* included from code that cares about pragmas */ +extern void arm_pr_long_calls PARAMS ((cpp_reader *)); +extern void arm_pr_no_long_calls PARAMS ((cpp_reader *)); +extern void arm_pr_long_calls_off PARAMS ((cpp_reader *)); +#endif + +#endif /* GCC_ARM_PROTOS_H */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index df4ed671eb5f..035ff1473074 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */ #include "system.h" #include "rtl.h" #include "tree.h" -#include "tm_p.h" +#include "tm.h" #include "regs.h" #include "hard-reg-set.h" #include "real.h" @@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */ #include "recog.h" #include "ggc.h" #include "except.h" +#include "c-pragma.h" #include "tm_p.h" /* Forward definitions of types. */ @@ -1613,27 +1614,27 @@ typedef enum static arm_pragma_enum arm_pragma_long_calls = OFF; -/* Handle pragmas for compatibility with Intel's compilers. - FIXME: This is incomplete, since it does not handle all - the pragmas that the Intel compilers understand. */ -int -arm_process_pragma (p_getc, p_ungetc, pname) - int (* p_getc) PARAMS ((void)) ATTRIBUTE_UNUSED; - void (* p_ungetc) PARAMS ((int)) ATTRIBUTE_UNUSED; - char * pname; -{ - /* Should be pragma 'far' or equivalent for callx/balx here. */ - if (strcmp (pname, "long_calls") == 0) - arm_pragma_long_calls = LONG; - else if (strcmp (pname, "no_long_calls") == 0) - arm_pragma_long_calls = SHORT; - else if (strcmp (pname, "long_calls_off") == 0) - arm_pragma_long_calls = OFF; - else - return 0; - - return 1; +void +arm_pr_long_calls (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + arm_pragma_long_calls = LONG; } + +void +arm_pr_no_long_calls (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + arm_pragma_long_calls = SHORT; +} + +void +arm_pr_long_calls_off (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + arm_pragma_long_calls = OFF; +} + /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific attribute for TYPE. The attributes in ATTRIBUTES have previously been diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 20615726cb75..4f2692a7ccfc 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2488,8 +2488,12 @@ extern int making_const_table; arm_set_default_type_attributes (TYPE) /* Handle pragmas for compatibility with Intel's compilers. */ -#define HANDLE_PRAGMA(GET, UNGET, NAME) arm_process_pragma (GET, UNGET, NAME) - +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \ + cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \ + cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \ +} while (0) + /* Condition code information. */ /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, return the mode to be used for the comparison. diff --git a/gcc/config/c4x/c4x-protos.h b/gcc/config/c4x/c4x-protos.h index cd7c0292bb5f..a9fb5e6bde29 100644 --- a/gcc/config/c4x/c4x-protos.h +++ b/gcc/config/c4x/c4x-protos.h @@ -22,6 +22,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_C4X_PROTOS_H +#define GCC_C4X_PROTOS_H + extern void c4x_override_options PARAMS ((void)); extern void c4x_optimization_options PARAMS ((int, int)); @@ -290,3 +293,14 @@ extern enum machine_mode c4x_caller_save_map[]; extern int c4x_rpts_cycles; /* Max cycles for RPTS. */ extern int c4x_cpu_version; /* Cpu version C30/31/32/40/44. */ + +#ifdef _C_PRAGMA_H +extern void c4x_pr_CODE_SECTION PARAMS ((cpp_reader *)); +extern void c4x_pr_DATA_SECTION PARAMS ((cpp_reader *)); +extern void c4x_pr_FUNC_IS_PURE PARAMS ((cpp_reader *)); +extern void c4x_pr_FUNC_NEVER_RETURNS PARAMS ((cpp_reader *)); +extern void c4x_pr_INTERRUPT PARAMS ((cpp_reader *)); +extern void c4x_pr_ignored PARAMS ((cpp_reader *)); +#endif + +#endif diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 49bfadc66a9b..d6881b5c2239 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -45,6 +45,9 @@ #include "recog.h" #include "c-tree.h" #include "ggc.h" +#include "cpplib.h" +#include "c-lex.h" +#include "c-pragma.h" #include "c4x-protos.h" rtx smulhi3_libfunc; @@ -182,6 +185,7 @@ static int c4x_valid_operands PARAMS ((enum rtx_code, rtx *, static int c4x_arn_reg_operand PARAMS ((rtx, enum machine_mode, unsigned int)); static int c4x_arn_mem_operand PARAMS ((rtx, enum machine_mode, unsigned int)); static void c4x_check_attribute PARAMS ((const char *, tree, tree, tree *)); +static int c4x_parse_pragma PARAMS ((const char *, tree *, tree *)); /* Called to register all of our global variables with the garbage collector. */ @@ -287,7 +291,7 @@ c4x_override_options () void c4x_optimization_options (level, size) - int level; + int level ATTRIBUTE_UNUSED; int size ATTRIBUTE_UNUSED; { /* Scheduling before register allocation can screw up global @@ -4383,123 +4387,112 @@ c4x_operand_subword (op, i, validate_address, mode) */ -int -c4x_handle_pragma (p_getc, p_ungetc, pname) - int (* p_getc) PARAMS ((void)); - void (* p_ungetc) PARAMS ((int)) ATTRIBUTE_UNUSED; - char *pname; +/* Parse a C4x pragma, of the form ( function [, "section"] ) \n. + FUNC is loaded with the IDENTIFIER_NODE of the function, SECT with + the STRING_CST node of the string. If SECT is null, then this + pragma doesn't take a section string. Returns 0 for a good pragma, + -1 for a malformed pragma. */ +#define BAD(msgid, arg) do { warning (msgid, arg); return -1; } while (0) + +static int +c4x_parse_pragma (name, func, sect) + const char *name; + tree *func; + tree *sect; { - int i; - int c; - int namesize; - char *name; - tree func; - tree sect = NULL_TREE; - tree new; + tree f, s, x; - c = p_getc (); - while (c == ' ' || c == '\t') c = p_getc (); - if (c != '(') - return 0; + if (c_lex (&x) != CPP_OPEN_PAREN) + BAD ("missing '(' after '#pragma %s' - ignored", name); - c = p_getc (); - while (c == ' ' || c == '\t') c = p_getc (); - if (! (ISALPHA(c) || c == '_' || c == '$' || c == '@')) - return 0; + if (c_lex (&f) != CPP_NAME) + BAD ("missing function name in '#pragma %s' - ignored", name); - i = 0; - namesize = 16; - name = xmalloc (namesize); - while (ISALNUM (c) || c == '_' || c == '$' || c == '@') - { - if (i >= namesize-1) - { - namesize += 16; - name = xrealloc (name, namesize); - } - name[i++] = c; - c = p_getc (); - } - name[i] = 0; - func = get_identifier (name); - free (name); - - if (strcmp (pname, "CODE_SECTION") == 0 - || strcmp (pname, "DATA_SECTION") == 0) + if (sect) { - while (c == ' ' || c == '\t') c = p_getc (); - if (c != ',') - return 0; - - c = p_getc (); - while (c == ' ' || c == '\t') c = p_getc (); - if (c != '"') - return 0; - - i = 0; - namesize = 16; - name = xmalloc (namesize); - c = p_getc (); - while (c != '"' && c != '\n' && c != '\r' && c != EOF) - { - if (i >= namesize-1) - { - namesize += 16; - name = xrealloc (name, namesize); - } - name[i++] = c; - c = p_getc (); - } - name[i] = 0; - sect = build_string (i, name); - free (name); - sect = build_tree_list (NULL_TREE, sect); - - if (c != '"') - return 0; - c = p_getc (); + if (c_lex (&x) != CPP_COMMA) + BAD ("malformed '#pragma %s' - ignored", name); + if (c_lex (&s) != CPP_STRING) + BAD ("missing section name in '#pragma %s' - ignored", name); + *sect = s; } - while (c == ' ' || c == '\t') c = p_getc (); - if (c != ')') - return 0; - - new = build_tree_list (func, sect); - if (strcmp (pname, "CODE_SECTION") == 0) - code_tree = chainon (code_tree, new); - - else if (strcmp (pname, "DATA_SECTION") == 0) - data_tree = chainon (data_tree, new); - - else if (strcmp (pname, "FUNC_CANNOT_INLINE") == 0) - ; /* Ignore. */ - - else if (strcmp (pname, "FUNC_EXT_CALLED") == 0) - ; /* Ignore. */ - - else if (strcmp (pname, "FUNC_IS_PURE") == 0) - pure_tree = chainon (pure_tree, new); - - else if (strcmp (pname, "FUNC_IS_SYSTEM") == 0) - ; /* Ignore. */ - - else if (strcmp (pname, "FUNC_NEVER_RETURNS") == 0) - noreturn_tree = chainon (noreturn_tree, new); - - else if (strcmp (pname, "FUNC_NO_GLOBAL_ASG") == 0) - ; /* Ignore. */ - - else if (strcmp (pname, "FUNC_NO_IND_ASG") == 0) - ; /* Ignore. */ - - else if (strcmp (pname, "INTERRUPT") == 0) - interrupt_tree = chainon (interrupt_tree, new); - - else - return 0; - - return 1; + + if (c_lex (&x) != CPP_CLOSE_PAREN) + BAD ("missing ')' for '#pragma %s' - ignored", name); + + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of '#pragma %s'", name); + + *func = f; + return 0; } +void +c4x_pr_CODE_SECTION (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree func, sect; + + if (c4x_parse_pragma ("CODE_SECTION", &func, §)) + return; + code_tree = chainon (code_tree, + build_tree_list (func, + build_tree_list (NULL_TREE, sect))); +} + +void +c4x_pr_DATA_SECTION (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree func, sect; + + if (c4x_parse_pragma ("DATA_SECTION", &func, §)) + return; + data_tree = chainon (data_tree, + build_tree_list (func, + build_tree_list (NULL_TREE, sect))); +} + +void +c4x_pr_FUNC_IS_PURE (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree func; + + if (c4x_parse_pragma ("FUNC_IS_PURE", &func, 0)) + return; + pure_tree = chainon (pure_tree, build_tree_list (func, NULL_TREE)); +} + +void +c4x_pr_FUNC_NEVER_RETURNS (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree func; + + if (c4x_parse_pragma ("FUNC_NEVER_RETURNS", &func, 0)) + return; + noreturn_tree = chainon (noreturn_tree, build_tree_list (func, NULL_TREE)); +} + +void +c4x_pr_INTERRUPT (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree func; + + if (c4x_parse_pragma ("INTERRUPT", &func, 0)) + return; + interrupt_tree = chainon (interrupt_tree, build_tree_list (func, NULL_TREE)); +} + +/* Used for FUNC_CANNOT_INLINE, FUNC_EXT_CALLED, FUNC_IS_SYSTEM, + FUNC_NO_GLOBAL_ASG, and FUNC_NO_IND_ASG. */ +void +c4x_pr_ignored (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ +} struct name_list { diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h index 7cc8169cbabf..8390b38b5863 100644 --- a/gcc/config/c4x/c4x.h +++ b/gcc/config/c4x/c4x.h @@ -2372,14 +2372,20 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) #define PRINT_OPERAND_ADDRESS(FILE, X) c4x_print_operand_address(FILE, X) -/* Define this macro if you want to implement any pragmas. If defined, it - should be a C expression to be executed when #pragma is seen. The - argument STREAM is the stdio input stream from which the source - text can be read. CH is the first character after the #pragma. The - result of the expression is the terminating character found - (newline or EOF). */ -#define HANDLE_PRAGMA(GETC, UNGETC, NAME) \ - c4x_handle_pragma (GETC, UNGETC, NAME) +/* C4x specific pragmas. */ +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma (PFILE, 0, "CODE_SECTION", c4x_pr_CODE_SECTION); \ + cpp_register_pragma (PFILE, 0, "DATA_SECTION", c4x_pr_DATA_SECTION); \ + cpp_register_pragma (PFILE, 0, "FUNC_CANNOT_INLINE", c4x_pr_ignored); \ + cpp_register_pragma (PFILE, 0, "FUNC_EXT_CALLED", c4x_pr_ignored); \ + cpp_register_pragma (PFILE, 0, "FUNC_IS_PURE", c4x_pr_FUNC_IS_PURE); \ + cpp_register_pragma (PFILE, 0, "FUNC_IS_SYSTEM", c4x_pr_ignored); \ + cpp_register_pragma (PFILE, 0, "FUNC_NEVER_RETURNS", \ + c4x_pr_FUNC_NEVER_RETURNS); \ + cpp_register_pragma (PFILE, 0, "FUNC_NO_GLOBAL_ASG", c4x_pr_ignored); \ + cpp_register_pragma (PFILE, 0, "FUNC_NO_IND_ASG", c4x_pr_ignored); \ + cpp_register_pragma (PFILE, 0, "INTERRUPT", c4x_pr_INTERRUPT); \ +} while (0) #define SET_DEFAULT_DECL_ATTRIBUTES(DECL, ATTRIBUTES) \ c4x_set_default_attributes (DECL, &ATTRIBUTES) diff --git a/gcc/config/d30v/d30v.h b/gcc/config/d30v/d30v.h index defdc4969531..9a4d2a4c1120 100644 --- a/gcc/config/d30v/d30v.h +++ b/gcc/config/d30v/d30v.h @@ -19,6 +19,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_D30V_H + /* D30V specific macros */ /* Align an address */ @@ -5955,15 +5957,6 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE) is to pretend that the file's contents are enclosed in `extern "C" {...}'. */ /* #define NO_IMPLICIT_EXTERN_C */ -/* Define this macro if you want to implement any pragmas. If defined, it - should be a C statement to be executed when `#pragma' is seen. The argument - STREAM is the stdio input stream from which the source text can be read. - - It is generally a bad idea to implement new uses of `#pragma'. The only - reason to define this macro is for compatibility with other compilers that - do support `#pragma' for the sake of any user programs which already use it. */ -/* #define HANDLE_PRAGMA(STREAM) */ - /* Define this macro to handle System V style pragmas (particularly #pack). Defined in svr4.h. */ @@ -6081,3 +6074,5 @@ extern const char *d30v_cond_exec_string; /* Indicate how many instructions can be issued at the same time. */ #define ISSUE_RATE 2 + +#endif /* GCC_D30V_H */ diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index d8e4e69ffbbb..1535b29c6f2e 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_H8300_PROTOS_H +#define GCC_H8300_PROTOS_H + /* Declarations for functions used in insn-output.c. */ #ifdef RTX_CODE extern const char *emit_a_shift PARAMS ((rtx, rtx *)); @@ -66,7 +69,6 @@ extern int h8300_tiny_data_p PARAMS ((tree)); extern void h8300_encode_label PARAMS ((tree)); #endif /* TREE_CODE */ -extern int handle_pragma PARAMS ((int (*)(void), void (*)(int), const char *)); extern void h8300_init_once PARAMS ((void)); extern void function_prologue PARAMS ((FILE *, int)); extern void function_epilogue PARAMS ((FILE *, int)); @@ -75,3 +77,10 @@ extern void asm_file_end PARAMS ((FILE *)); extern int ok_for_bclr PARAMS ((HOST_WIDE_INT)); extern int small_power_of_two PARAMS ((HOST_WIDE_INT)); extern int initial_offset PARAMS ((int, int)); + +#ifdef _C_PRAGMA_H +extern void h8300_pr_interrupt PARAMS ((cpp_reader *)); +extern void h8300_pr_saveall PARAMS ((cpp_reader *)); +#endif + +#endif /* GCC_H8300_PROTOS_H */ diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index ec1432a1d8c9..1ecda26af58c 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA. */ #include "function.h" #include "obstack.h" #include "toplev.h" +#include "c-pragma.h" #include "tm_p.h" /* Forward declarations. */ @@ -730,22 +731,20 @@ eq_operator (x, mode) an rte instruction rather than an rts. A pointer to a function with this attribute may be safely used in an interrupt vector. */ -int -handle_pragma (p_getc, p_ungetc, pname) - int (* ATTRIBUTE_UNUSED p_getc) PARAMS ((void)); - void (* ATTRIBUTE_UNUSED p_ungetc) PARAMS ((int)); - const char *pname; +void +h8300_pr_interrupt (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; { - int retval = 0; - - if (strcmp (pname, "interrupt") == 0) - interrupt_handler = retval = 1; - else if (strcmp (pname, "saveall") == 0) - pragma_saveall = retval = 1; + interrupt_handler = 1; +} - return retval; +void +h8300_pr_saveall (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + pragma_saveall = 1; } - + /* If the next arg with MODE and TYPE is to be passed in a register, return the rtx to represent where it is passed. CUM represents the state after the last argument. NAMED is not used. */ diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index ebd05fe983c1..55af2e297e15 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -22,6 +22,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_H8300_H +#define GCC_H8300_H + /* Which CPU to compile for. We use int for CPU_TYPE to avoid lots of casts. */ #if 0 /* defined in insn-attr.h, here for documentation */ @@ -1410,18 +1413,11 @@ do { char dstr[30]; \ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) -/* Define this macro if you want to implement any pragmas. If defined, it - should be a C expression to be executed when #pragma is seen. The - argument GETC is a function which will return the next character in the - input stream, or EOF if no characters are left. The argument UNGETC is - a function which will push a character back into the input stream. The - argument NAME is the word following #pragma in the input stream. The input - stream pointer will be pointing just beyond the end of this word. The - expression should return true if it handled the pragma, false otherwise. - The input stream should be left undistrubed if false is returned, otherwise - it should be pointing at the last character after the end of the pragma - (newline or end-of-file). */ -#define HANDLE_PRAGMA(GETC, UNGETC, NAME) handle_pragma (GETC, UNGETC, NAME) +/* H8300 specific pragmas. */ +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma (PFILE, 0, "saveall", h8300_pr_saveall); \ + cpp_register_pragma (PFILE, 0, "interrupt", h8300_pr_interrupt); \ +} while (0) #define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop) @@ -1454,3 +1450,5 @@ do { char dstr[30]; \ } while (0) #define MOVE_RATIO 3 + +#endif /* GCC_H8300_H */ diff --git a/gcc/config/i370/i370-protos.h b/gcc/config/i370/i370-protos.h index 7e64acd8ed20..7ee1d3ff6e1b 100644 --- a/gcc/config/i370/i370-protos.h +++ b/gcc/config/i370/i370-protos.h @@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_I370_PROTOS_H +#define GCC_I370_PROTOS_H + #ifdef RTX_CODE extern int i370_branch_dest PARAMS ((rtx)); extern int i370_branch_length PARAMS ((rtx)); @@ -46,3 +49,9 @@ extern int mvs_check_alias PARAMS ((const char *, char *)); extern void i370_function_prolog PARAMS ((FILE *, int)); extern void check_label_emit PARAMS ((void)); extern void mvs_free_label_list PARAMS ((void)); + +#ifdef _C_PRAGMA_H +extern void i370_pr_map PARAMS ((cpp_reader *)); +#endif + +#endif diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c index 2aa7d31ee25a..73a78803e336 100644 --- a/gcc/config/i370/i370.c +++ b/gcc/config/i370/i370.c @@ -38,6 +38,9 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "recog.h" #include "toplev.h" +#include "cpplib.h" +#include "c-pragma.h" +#include "c-lex.h" #include "tm_p.h" extern FILE *asm_out_file; @@ -862,6 +865,17 @@ mvs_add_alias (realname, aliasname, emitted) alias_node_t *ap; ap = (alias_node_t *) xmalloc (sizeof (alias_node_t)); + if (strlen (realname) > MAX_LONG_LABEL_SIZE) + { + warning ("real name is too long - alias ignored"); + return; + } + if (strlen (aliasname) > MAX_MVS_LABEL_SIZE) + { + warning ("alias name is too long - alias ignored"); + return; + } + strcpy (ap->real_name, realname); strcpy (ap->alias_name, aliasname); ap->alias_emitted = emitted; @@ -1005,116 +1019,31 @@ mvs_check_alias (realname, aliasname) return 0; } -/* Called from check_newline via the macro HANDLE_PRAGMA. - p_getc is a pointer to get character routine. - p_ungetc is a pointer to un-get character routine. - pname is the pointer to the name of the pragma to process. - The result is 1 if the pragma was handled. */ +/* #pragma map (name, alias) - + In this implementation both name and alias are required to be + identifiers. The older code seemed to be more permissive. Can + anyone clarify? */ -int -handle_pragma (p_getc, p_ungetc, pname) - int (* p_getc) PARAMS ((void)); - void (* p_ungetc) PARAMS ((int)); - const char *pname; +void +i370_pr_map (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; { - int retval = 0; - register int c; + tree name, alias, x; - if (strcmp (pname, "map") == 0) + if (c_lex (&x) == CPP_OPEN_PAREN + && c_lex (&name) == CPP_NAME + && c_lex (&x) == CPP_COMMA + && c_lex (&alias) == CPP_NAME + && c_lex (&x) == CPP_CLOSE_PAREN) { - char realname[MAX_LONG_LABEL_SIZE + 1]; - char aliasname[MAX_MVS_LABEL_SIZE + 1]; - char *s; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma map"); - do { - c = p_getc (); - } while (c == ' ' || c == '\t'); - - if (c == '(') - { - s = realname; - do { - c = p_getc (); - } while (c == ' ' || c == '\t'); - if (c == '\n') - goto PRAGMA_WARNING; - do { - *s++ = c; - c = p_getc (); - } while (ISALNUM(c) || c == '_'); - if (c == '\n') - goto PRAGMA_WARNING; - *s = 0; - - if (c == ' ' || c == '\t') - do { - c = p_getc (); - } while (c == ' ' || c == '\t'); - - if (c == ',') - { - do { - c = p_getc (); - } while (c == ' ' || c == '\t'); - if (c == '"') - { - s = aliasname; - c = p_getc (); - do { - if (c == '\\') - { - int d = 0; - do { - c = p_getc (); - if (c >= '0' && c <= '7') - d = (d << 3) | (c - '0'); - } while (c >= '0' && c <= '7'); - p_ungetc (c); - c = d; - if (d < 1 || d > 255) - warning ("Escape value out of range"); -#ifndef HOST_EBCDIC - c = ebcasc[c]; -#endif - } - *s++ = c; - c = p_getc (); - if (ISSPACE(c) || c == ')') - goto PRAGMA_WARNING; - } while (c != '"'); - *s = 0; - if (strlen (aliasname) > MAX_MVS_LABEL_SIZE) - { - warning ("#pragma map alias is too long, truncated"); - aliasname[MAX_MVS_LABEL_SIZE] = '\0'; - } - do { - c = p_getc (); - } while (c == ' ' || c == '\t'); - if (c == ')') - { - mvs_add_alias (realname, aliasname, 1); - retval = 1; - } - else - goto PRAGMA_WARNING; - } - else - goto PRAGMA_WARNING; - } - else - goto PRAGMA_WARNING; - - } - else - { - PRAGMA_WARNING: - warning ("#pragma map options are missing or incorrect"); - } - + mvs_add_alias (IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (alias), 1); + return; } - return retval; + warning ("malformed #pragma map, ignored"); } /* defines and functions specific to the HLASM assembler */ diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h index eccbcb6e56b5..b73328305081 100644 --- a/gcc/config/i370/i370.h +++ b/gcc/config/i370/i370.h @@ -147,14 +147,9 @@ extern int mvs_function_name_length; #endif #ifdef TARGET_HLASM -/* Define this macro if you want to implement any pragmas. If defined, it - is a C expression to be executed when #pragma is seen. The - argument FILE is the stdio input stream from which the source - text can be read. CH is the first character after the #pragma. The - result of the expression is the terminating character found - (newline or EOF). */ -#define HANDLE_PRAGMA(GETC, UNGETC, NAME) \ - handle_pragma ((GETC), (UNGETC), (NAME)) +/* HLASM requires #pragma map. */ +#define REGISTER_TARGET_PRAGMAS(PFILE) \ + cpp_register_pragma (PFILE, 0, "map", i370_pr_map) #endif /* TARGET_HLASM */ /* Define maximum length of page minus page escape overhead. */ diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md index 3bdb025c2aa6..14bc9488f675 100644 --- a/gcc/config/i370/i370.md +++ b/gcc/config/i370/i370.md @@ -2714,7 +2714,6 @@ check_label_emit (); { rtx dr = gen_reg_rtx (DImode); rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0); - rtx dr_1 = gen_rtx_SUBREG (SImode, dr, 1); emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1])); @@ -4717,7 +4716,7 @@ check_label_emit (); { int i; - emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx)); + emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx)); for (i = 0; i < XVECLEN (operands[2], 0); i++) { diff --git a/gcc/config/i960/i960-protos.h b/gcc/config/i960/i960-protos.h index 92357c9b0e72..130dddeefe40 100644 --- a/gcc/config/i960/i960-protos.h +++ b/gcc/config/i960/i960-protos.h @@ -22,6 +22,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_I960_PROTOS_H +#define GCC_I960_PROTOS_H + #ifdef RTX_CODE extern struct rtx_def *legitimize_address PARAMS ((rtx, rtx, enum machine_mode)); /* Define the function that build the compare insn for scc and bcc. */ @@ -102,3 +105,10 @@ extern void i960_function_prologue PARAMS ((FILE *, unsigned int)); extern void output_function_profiler PARAMS ((FILE *, int)); extern void i960_function_epilogue PARAMS ((FILE *, unsigned int)); extern void i960_scan_opcode PARAMS ((const char *)); + +#ifdef _C_PRAGMA_H +extern void i960_pr_align PARAMS ((cpp_reader *)); +extern void i960_pr_noalign PARAMS ((cpp_reader *)); +#endif + +#endif /* i960-protos.h */ diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c index e8e046db2e4c..21753a207b2c 100644 --- a/gcc/config/i960/i960.c +++ b/gcc/config/i960/i960.c @@ -42,6 +42,9 @@ Boston, MA 02111-1307, USA. */ #include "function.h" #include "recog.h" #include "toplev.h" +#include "cpplib.h" +#include "c-pragma.h" +#include "c-lex.h" #include "tm_p.h" /* Save the operands last given to a compare for use when we @@ -88,8 +91,86 @@ static int ret_label = 0; /* Handle pragmas for compatibility with Intel's compilers. */ -/* ??? This is incomplete, since it does not handle all pragmas that the - intel compilers understand. */ +/* NOTE: ic960 R3.0 pragma align definition: + + #pragma align [(size)] | (identifier=size[,...]) + #pragma noalign [(identifier)[,...]] + + (all parens are optional) + + - size is [1,2,4,8,16] + - noalign means size==1 + - applies only to component elements of a struct (and union?) + - identifier applies to structure tag (only) + - missing identifier means next struct + + - alignment rules for bitfields need more investigation. + + This implementation only handles the case of no identifiers. */ + +void +i960_pr_align (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree number; + enum cpp_ttype type; + int align; + + type = c_lex (&number); + if (type == CPP_OPEN_PAREN) + type = c_lex (&number); + if (type == CPP_NAME) + { + warning ("sorry, not implemented: #pragma align NAME=SIZE"); + return; + } + if (type != CPP_NUMBER) + { + warning ("malformed #pragma align - ignored"); + return; + } + + align = TREE_INT_CST_LOW (number); + switch (align) + { + case 0: + /* Return to last alignment. */ + align = i960_last_maxbitalignment / 8; + /* Fall through. */ + case 16: + case 8: + case 4: + case 2: + case 1: + i960_last_maxbitalignment = i960_maxbitalignment; + i960_maxbitalignment = align * 8; + break; + + default: + /* Silently ignore bad values. */ + break; + } +} + +void +i960_pr_noalign (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + enum cpp_ttype type; + tree number; + + type = c_lex (&number); + if (type == CPP_OPEN_PAREN) + type = c_lex (&number); + if (type == CPP_NAME) + { + warning ("sorry, not implemented: #pragma noalign NAME"); + return; + } + + i960_last_maxbitalignment = i960_maxbitalignment; + i960_maxbitalignment = 8; +} int process_pragma (p_getc, p_ungetc, pname) @@ -132,40 +213,7 @@ process_pragma (p_getc, p_ungetc, pname) align = atoi (buf); - switch (align) - { - case 0: - /* Return to last alignment. */ - align = i960_last_maxbitalignment / 8; - /* Fall through. */ - case 16: - case 8: - case 4: - case 2: - case 1: - i960_last_maxbitalignment = i960_maxbitalignment; - i960_maxbitalignment = align * 8; - break; - - default: - /* Silently ignore bad values. */ - break; - } - /* NOTE: ic960 R3.0 pragma align definition: - - #pragma align [(size)] | (identifier=size[,...]) - #pragma noalign [(identifier)[,...]] - - (all parens are optional) - - - size is [1,2,4,8,16] - - noalign means size==1 - - applies only to component elements of a struct (and union?) - - identifier applies to structure tag (only) - - missing identifier means next struct - - - alignment rules for bitfields need more investigation */ return 1; } diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h index 66be5f624eaa..c741ba45263b 100644 --- a/gcc/config/i960/i960.h +++ b/gcc/config/i960/i960.h @@ -131,7 +131,10 @@ Boston, MA 02111-1307, USA. */ fprintf (asm_out_file, "\t.type\t0x%x;", A) /* Handle pragmas for compatibility with Intel's compilers. */ -#define HANDLE_PRAGMA(GET, UNGET, NAME) process_pragma (GET, UNGET, NAME) +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma (PFILE, 0, "align", i960_pr_align); \ + cpp_register_pragma (PFILE, 0, "noalign", i960_pr_noalign); \ +} while (0) /* Run-time compilation parameters selecting different hardware subsets. */ diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h index 148b6b973b1b..435aff17cf77 100644 --- a/gcc/config/sh/elf.h +++ b/gcc/config/sh/elf.h @@ -112,10 +112,6 @@ do { \ fprintf ((FILE), "\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO); \ } while (0) -/* HANDLE_SYSV_PRAGMA (defined by svr4.h) takes precedence over HANDLE_PRAGMA. - We want to use the HANDLE_PRAGMA from sh.h. */ -#undef HANDLE_SYSV_PRAGMA - #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: crt1.o%s} crti.o%s \ diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index fc441a97febe..e62edf4dba03 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_SH_PROTOS_H +#define GCC_SH_PROTOS_H + #ifdef RTX_CODE extern struct rtx_def *sh_builtin_saveregs PARAMS ((void)); extern struct rtx_def *prepare_scc_operands PARAMS ((enum rtx_code)); @@ -122,3 +125,11 @@ extern int fldi_ok PARAMS ((void)); #ifdef HARD_CONST extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET)); #endif + +#ifdef _C_PRAGMA_H +extern void sh_pr_interrupt PARAMS ((cpp_reader *)); +extern void sh_pr_trapa PARAMS ((cpp_reader *)); +extern void sh_pr_nosave_low_regs PARAMS ((cpp_reader *)); +#endif + +#endif /* sh-protos.h */ diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 20babcbb6a56..158e66f31774 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ #include "insn-attr.h" #include "toplev.h" #include "recog.h" +#include "c-pragma.h" #include "tm_p.h" int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch; @@ -4443,22 +4444,25 @@ initial_elimination_offset (from, to) /* Handle machine specific pragmas to be semi-compatible with Hitachi compiler. */ -int -sh_handle_pragma (p_getc, p_ungetc, pname) - int (* p_getc) PARAMS ((void)) ATTRIBUTE_UNUSED; - void (* p_ungetc) PARAMS ((int)) ATTRIBUTE_UNUSED; - const char * pname; +void +sh_pr_interrupt (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; { - int retval = 0; + pragma_interrupt = 1; +} - if (strcmp (pname, "interrupt") == 0) - pragma_interrupt = retval = 1; - else if (strcmp (pname, "trapa") == 0) - pragma_interrupt = pragma_trapa = retval = 1; - else if (strcmp (pname, "nosave_low_regs") == 0) - pragma_nosave_low_regs = retval = 1; +void +sh_pr_trapa (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + pragma_interrupt = pragma_trapa = 1; +} - return retval; +void +sh_pr_nosave_low_regs (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + pragma_nosave_low_regs = 1; } /* Generate 'handle_interrupt' attribute for decls */ diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 78efca5d1a3b..1fab69f74dc3 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -21,6 +21,8 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_SH_H +#define GCC_SH_H #define TARGET_VERSION \ fputs (" (Hitachi SH)", stderr); @@ -2185,10 +2187,12 @@ extern enum mdep_reorg_phase_e mdep_reorg_phase; #define TARGET_MEM_FUNCTIONS -/* 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 - macro, zero otherwise. */ -#define HANDLE_PRAGMA(GETC, UNGETC, NODE) sh_handle_pragma (GETC, UNGETC, NODE) +/* Handle Hitachi compiler's pragmas. */ +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma (PFILE, 0, "interrupt", sh_pr_interrupt); \ + cpp_register_pragma (PFILE, 0, "trapa", sh_pr_trapa); \ + cpp_register_pragma (PFILE, 0, "nosave_low_regs", sh_pr_nosave_low_regs); \ +} while (0) /* Set when processing a function with pragma interrupt turned on. */ @@ -2369,3 +2373,5 @@ do { \ 0: .p2align 2\n\ 1: .long " USER_LABEL_PREFIX #func " - 0b\n\ 2:") + +#endif /* sh.h */ diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h index d6155fd264d7..03be1346ebb0 100644 --- a/gcc/config/v850/v850-protos.h +++ b/gcc/config/v850/v850-protos.h @@ -20,6 +20,9 @@ Boston, MA 02111-1307, USA. */ /* Function prototypes that cannot exist in v850.h due to dependency compilcations. */ +#ifndef GCC_V850_PROTOS_H +#define GCC_V850_PROTOS_H + #define Mmode enum machine_mode extern void expand_prologue PARAMS ((void)); @@ -41,8 +44,8 @@ extern int compute_frame_size PARAMS ((int, long *)); extern void print_operand PARAMS ((FILE *, rtx, int )); extern void print_operand_address PARAMS ((FILE *, rtx)); extern int const_costs PARAMS ((rtx, enum rtx_code)); -extern char * output_move_double PARAMS ((rtx *)); -extern char * output_move_single PARAMS ((rtx *)); +extern const char *output_move_double PARAMS ((rtx *)); +extern const char *output_move_single PARAMS ((rtx *)); extern void v850_reorg PARAMS ((rtx)); extern void notice_update_cc PARAMS ((rtx, rtx)); extern char * construct_save_jarl PARAMS ((rtx)); @@ -80,5 +83,17 @@ extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *, Mmode, t #endif #endif +#ifdef _C_PRAGMA_H +extern void ghs_pragma_section PARAMS ((cpp_reader *)); +extern void ghs_pragma_interrupt PARAMS ((cpp_reader *)); +extern void ghs_pragma_starttda PARAMS ((cpp_reader *)); +extern void ghs_pragma_startsda PARAMS ((cpp_reader *)); +extern void ghs_pragma_startzda PARAMS ((cpp_reader *)); +extern void ghs_pragma_endtda PARAMS ((cpp_reader *)); +extern void ghs_pragma_endsda PARAMS ((cpp_reader *)); +extern void ghs_pragma_endzda PARAMS ((cpp_reader *)); +#endif + #undef Mmode +#endif /* v850-protos.h */ diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index c3b6cf1dc77f..e4365e042c8a 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -37,7 +37,10 @@ Boston, MA 02111-1307, USA. */ #include "function.h" #include "obstack.h" #include "toplev.h" -#include "v850-protos.h" +#include "cpplib.h" +#include "c-lex.h" +#include "c-pragma.h" +#include "tm_p.h" #ifndef streq #define streq(a,b) (strcmp (a, b) == 0) @@ -50,7 +53,6 @@ static int const_costs_int PARAMS ((HOST_WIDE_INT, int)); static void substitute_ep_register PARAMS ((rtx, rtx, int, int, rtx *, rtx *)); static int push_data_area PARAMS ((v850_data_area)); static int pop_data_area PARAMS ((v850_data_area)); -static int parse_ghs_pragma_token PARAMS ((char *)); static int ep_memory_offset PARAMS ((enum machine_mode, int)); static int mark_current_function_as_interrupt PARAMS ((void)); static void v850_set_data_area PARAMS ((tree, v850_data_area)); @@ -441,7 +443,7 @@ print_operand (file, x, code) case 'Q': if (special_symbolref_operand (x, VOIDmode)) { - char* name; + const char *name; if (GET_CODE (x) == SYMBOL_REF) name = XSTR (x, 0); @@ -667,7 +669,7 @@ print_operand_address (file, addr) /* Return appropriate code to load up a 1, 2, or 4 integer/floating point value. */ -char * +const char * output_move_single (operands) rtx *operands; { @@ -759,7 +761,7 @@ output_move_single (operands) /* Return appropriate code to load up an 8 byte integer or floating point value */ -char * +const char * output_move_double (operands) rtx *operands; { @@ -2726,292 +2728,151 @@ mark_current_function_as_interrupt () (name, NULL_TREE, current_function_decl, NULL_TREE); } -/* Parse STRING as part of a GHS pragma. - Returns 0 if the pragma has been parsed and there was a problem, - non-zero in all other cases. */ -static int -parse_ghs_pragma_token (string) - char * string; +/* Support for GHS pragmata. */ + +void +ghs_pragma_section (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; { - static enum v850_pragma_state state = V850_PS_START; - static enum v850_pragma_type type = V850_PT_UNKNOWN; - static v850_data_area data_area = DATA_AREA_NORMAL; - static char * data_area_name; - static enum GHS_section_kind GHS_section_kind = GHS_SECTION_KIND_DEFAULT; - - /* If the string is NULL then we have reached the end of the - #pragma construct. Make sure that we are in an end state, and - then implement the pragma's directive. */ - if (string == NULL) - { - int ret_val = 1; - - if (state != V850_PS_SHOULD_BE_DONE - && state != V850_PS_MAYBE_COMMA - && state != V850_PS_MAYBE_SECTION_NAME) - { - if (state != V850_PS_BAD) - warning ("Incomplete #pragma ghs"); + int repeat; + + /* #pragma ghs section [name = alias [, name = alias [, ...]]] */ + do { + tree x; + enum cpp_ttype type; + const char *sect, *alias; + enum GHS_section_kind kind; + + type = c_lex (&x); + if (type == CPP_EOF && !repeat) + goto reset; + else if (type == CPP_NAME) + sect = IDENTIFIER_POINTER (x); + else + goto bad; + repeat = 0; + + if (c_lex (&x) != CPP_EQ) + goto bad; + if (c_lex (&x) != CPP_NAME) + goto bad; + alias = IDENTIFIER_POINTER (x); + + type = c_lex (&x); + if (type == CPP_COMMA) + repeat = 1; + else if (type != CPP_EOF) + warning ("junk at end of #pragma ghs section"); + + if (streq (sect, "data")) kind = GHS_SECTION_KIND_DATA; + else if (streq (sect, "text")) kind = GHS_SECTION_KIND_TEXT; + else if (streq (sect, "rodata")) kind = GHS_SECTION_KIND_RODATA; + else if (streq (sect, "const")) kind = GHS_SECTION_KIND_RODATA; + else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA; + else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA; + else if (streq (sect, "sdata")) kind = GHS_SECTION_KIND_SDATA; + else if (streq (sect, "tdata")) kind = GHS_SECTION_KIND_TDATA; + else if (streq (sect, "zdata")) kind = GHS_SECTION_KIND_ZDATA; + /* According to GHS beta documentation, the following should not be + allowed! */ + else if (streq (sect, "bss")) kind = GHS_SECTION_KIND_BSS; + else if (streq (sect, "zbss")) kind = GHS_SECTION_KIND_ZDATA; + else + { + warning ("unrecognised section name \"%s\"", sect); + return; + } - ret_val = 0; - } - else switch (type) - { - case V850_PT_UNKNOWN: - warning ("Nothing follows #pragma ghs"); - ret_val = 0; - break; - - case V850_PT_INTERRUPT: - ret_val = mark_current_function_as_interrupt (); - break; - - case V850_PT_SECTION: - /* If a section kind has not been specified, then reset - all section names back to their defaults. */ - if (GHS_section_kind == GHS_SECTION_KIND_DEFAULT) - { - int i; - - for (i = COUNT_OF_GHS_SECTION_KINDS; i--;) - GHS_current_section_names [i] = NULL; - } - /* If a section has been specified, then this will be handled - by check_default_section_name (). */ - break; - - case V850_PT_START_SECTION: - ret_val = push_data_area (data_area); - break; - - case V850_PT_END_SECTION: - ret_val = pop_data_area (data_area); - break; - } + if (streq (alias, "default")) + GHS_current_section_names [kind] = NULL; + else + GHS_current_section_names [kind] = + build_string (strlen (alias) + 1, alias); - state = V850_PS_START; - type = V850_PT_UNKNOWN; - - return ret_val; - } - - switch (state) - { - case V850_PS_START: - data_area = DATA_AREA_NORMAL; - data_area_name = NULL; - - if (streq (string, "interrupt")) - { - type = V850_PT_INTERRUPT; - state = V850_PS_SHOULD_BE_DONE; - } - else if (streq (string, "section")) - { - type = V850_PT_SECTION; - state = V850_PS_MAYBE_SECTION_NAME; - GHS_section_kind = GHS_SECTION_KIND_DEFAULT; - } - else if (streq (string, "starttda")) - { - type = V850_PT_START_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_TDA; - } - else if (streq (string, "endtda")) - { - type = V850_PT_END_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_TDA; - } - else if (streq (string, "startsda")) - { - type = V850_PT_START_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_SDA; - } - else if (streq (string, "endsda")) - { - type = V850_PT_END_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_SDA; - } - else if (streq (string, "startzda")) - { - type = V850_PT_START_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_ZDA; - } - else if (streq (string, "endzda")) - { - type = V850_PT_END_SECTION; - state = V850_PS_SHOULD_BE_DONE; - data_area = DATA_AREA_ZDA; - } - else - { - warning ("Unrecognised GHS pragma: '%s'\n", string); - state = V850_PS_BAD; - } - break; - - case V850_PS_SHOULD_BE_DONE: - warning ("Extra text after valid #pragma: '%s'", string); - state = V850_PS_BAD; - break; - - case V850_PS_BAD: - /* Ignore tokens in a pragma that has been diagnosed as being corrupt. */ - break; + } while (repeat); + return; - case V850_PS_MAYBE_SECTION_NAME: - state = V850_PS_EXPECTING_EQUALS; - - if (streq (string, "data")) GHS_section_kind = GHS_SECTION_KIND_DATA; - else if (streq (string, "text")) GHS_section_kind = GHS_SECTION_KIND_TEXT; - else if (streq (string, "rodata")) GHS_section_kind = GHS_SECTION_KIND_RODATA; - else if (streq (string, "const")) GHS_section_kind = GHS_SECTION_KIND_RODATA; - else if (streq (string, "rosdata")) GHS_section_kind = GHS_SECTION_KIND_ROSDATA; - else if (streq (string, "rozdata")) GHS_section_kind = GHS_SECTION_KIND_ROZDATA; - else if (streq (string, "sdata")) GHS_section_kind = GHS_SECTION_KIND_SDATA; - else if (streq (string, "tdata")) GHS_section_kind = GHS_SECTION_KIND_TDATA; - else if (streq (string, "zdata")) GHS_section_kind = GHS_SECTION_KIND_ZDATA; - /* According to GHS beta documentation, the following should not be allowed! */ - else if (streq (string, "bss")) GHS_section_kind = GHS_SECTION_KIND_BSS; - else if (streq (string, "zbss")) GHS_section_kind = GHS_SECTION_KIND_ZDATA; - else - { - warning ("Unrecognised section name '%s' in GHS section pragma", - string); - state = V850_PS_BAD; - } - break; + bad: + warning ("malformed #pragma ghs section"); + return; - case V850_PS_EXPECTING_EQUALS: - if (streq (string, "=")) - state = V850_PS_EXPECTING_SECTION_ALIAS; - else - { - warning ("Missing '=' in GHS section pragma"); - state = V850_PS_BAD; - } - break; - - case V850_PS_EXPECTING_SECTION_ALIAS: - if (streq (string, "default")) - GHS_current_section_names [GHS_section_kind] = NULL; - else - GHS_current_section_names [GHS_section_kind] = - build_string (strlen (string) + 1, string); - - state = V850_PS_MAYBE_COMMA; - break; - - case V850_PS_MAYBE_COMMA: - if (streq (string, ",")) - state = V850_PS_MAYBE_SECTION_NAME; - else - { - warning - ("Malformed GHS section pragma: found '%s' instead of a comma", - string); - state = V850_PS_BAD; - } - break; - } - - return 1; + reset: + /* #pragma ghs section \n: Reset all section names back to their defaults. */ + { + int i; + for (i = COUNT_OF_GHS_SECTION_KINDS; i--;) + GHS_current_section_names [i] = NULL; + } } -/* Handle the parsing of an entire GHS pragma. */ -int -v850_handle_pragma (p_getc, p_ungetc, name) - int (* p_getc) PARAMS ((void)); - void (* p_ungetc) PARAMS ((int)); - char * name; +void +ghs_pragma_interrupt (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; { - /* Parse characters in the input stream until: - - * end of line - * end of file - * a complete GHS pragma has been parsed - * a corrupted GHS pragma has been parsed - * an unknown pragma is encountered. - - If an unknown pragma is encountered, we must return with - the input stream in the same state as upon entry to this function. - - The first token in the input stream has already been parsed - for us, and is passed as 'name'. */ - - if (! streq (name, "ghs")) - return 0; - - /* We now know that we are parsing a GHS pragma, so we do - not need to preserve the original input stream state. */ - for (;;) - { - static char buffer [128]; - int c; - char * buff; - - /* Skip white space. */ - do - c = p_getc (); - while (c == ' ' || c == '\t'); - - p_ungetc (c); - - if (c == '\n' || c == EOF || c == '\r') - return parse_ghs_pragma_token (NULL); + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs interrupt"); + mark_current_function_as_interrupt (); +} - /* Read next word. We have to do the parsing ourselves, rather - than calling yylex() because we can be built with front ends - that do not provide such functions. */ - buff = buffer; - * buff ++ = (c = p_getc ()); +void +ghs_pragma_starttda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs starttda"); + push_data_area (DATA_AREA_TDA); +} - switch (c) - { - case ',': - case '=': - * buff ++ = (c = p_getc ()); - break; - - case '"': - /* Skip opening double parenthesis. */ - -- buff; - - /* Read string. */ - do - * buff ++ = (c = p_getc ()); - while (c != EOF && (ISALNUM (c) || c == '_' || c == '.' || c == ' ') - && (buff < buffer + 126)); - - if (c != '"') - warning ("Missing trailing \" in #pragma ghs"); - else - c = p_getc (); - break; +void +ghs_pragma_startsda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs startsda"); + push_data_area (DATA_AREA_SDA); +} - default: - while (c != EOF && (ISALNUM (c) || c == '_' || c == '.') - && (buff < buffer + 126)) - * buff ++ = (c = p_getc ()); - break; - } +void +ghs_pragma_startzda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs startzda"); + push_data_area (DATA_AREA_ZDA); +} - p_ungetc (c); +void +ghs_pragma_endtda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs endtda"); + pop_data_area (DATA_AREA_TDA); +} - /* If nothing was read then terminate the parsing. */ - if (buff == buffer + 1) - return parse_ghs_pragma_token (NULL); +void +ghs_pragma_endsda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs endsda"); + pop_data_area (DATA_AREA_SDA); +} - /* Parse and continue. */ - * -- buff = 0; - - parse_ghs_pragma_token (buffer); - } +void +ghs_pragma_endzda (pfile) + cpp_reader *pfile ATTRIBUTE_UNUSED; +{ + tree x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma ghs endzda"); + pop_data_area (DATA_AREA_ZDA); } /* Add data area to the given declaration if a ghs data area pragma is diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 88267e7ac950..dfe4b20e4c18 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -19,6 +19,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_V850_H +#define GCC_V850_H + #include "svr4.h" /* Automatically does #undef CPP_PREDEFINES */ /* These are defiend in svr4.h but we want to override them. */ @@ -138,7 +141,7 @@ extern int target_flags; /* Information about the various small memory areas. */ struct small_memory_info { - char *name; + const char *name; const char *value; long max; long physical_max; @@ -1505,27 +1508,17 @@ do { char dstr[30]; \ v850_set_default_decl_attr (decl) /* Tell compiler we want to support GHS pragmas */ -#define HANDLE_PRAGMA(get, unget, name) v850_handle_pragma (get, unget, name) - -enum v850_pragma_state -{ - V850_PS_START, - V850_PS_SHOULD_BE_DONE, - V850_PS_BAD, - V850_PS_MAYBE_SECTION_NAME, - V850_PS_EXPECTING_EQUALS, - V850_PS_EXPECTING_SECTION_ALIAS, - V850_PS_MAYBE_COMMA -}; - -enum v850_pragma_type -{ - V850_PT_UNKNOWN, - V850_PT_INTERRUPT, - V850_PT_SECTION, - V850_PT_START_SECTION, - V850_PT_END_SECTION -}; +#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ + cpp_register_pragma_space (PFILE, "ghs"); \ + cpp_register_pragma (PFILE, "ghs", "interrupt", ghs_pragma_interrupt); \ + cpp_register_pragma (PFILE, "ghs", "section", ghs_pragma_section); \ + cpp_register_pragma (PFILE, "ghs", "starttda", ghs_pragma_starttda); \ + cpp_register_pragma (PFILE, "ghs", "startsda", ghs_pragma_startsda); \ + cpp_register_pragma (PFILE, "ghs", "startzda", ghs_pragma_startzda); \ + cpp_register_pragma (PFILE, "ghs", "endtda", ghs_pragma_endtda); \ + cpp_register_pragma (PFILE, "ghs", "endsda", ghs_pragma_endsda); \ + cpp_register_pragma (PFILE, "ghs", "endzda", ghs_pragma_endzda); \ +} while (0) /* 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 @@ -1621,3 +1614,4 @@ enum GHS_section_kind { "register_is_ok_for_epilogue",{ REG }}, \ { "not_power_of_two_operand", { CONST_INT }}, +#endif /* v850.h */ diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 1163c2e289cf..75f038f842f0 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -28,7 +28,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern "C" { #endif +/* For complex reasons, cpp_reader is also typedefed in c-pragma.h. */ +#ifndef _C_PRAGMA_H typedef struct cpp_reader cpp_reader; +#endif typedef struct cpp_buffer cpp_buffer; typedef struct cpp_options cpp_options; typedef struct cpp_printer cpp_printer; diff --git a/gcc/tm.texi b/gcc/tm.texi index 838fd7d349e4..41ce0ee0e034 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -7774,33 +7774,62 @@ C++, which is to pretend that the file's contents are enclosed in @samp{extern "C" @{@dots{}@}}. @findex HANDLE_PRAGMA +@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name}) +This macro is no longer supported. You must use +@code{REGISTER_TARGET_PRAGMAS} instead. + +@findex REGISTER_TARGET_PRAGMAS @findex #pragma @findex pragma -@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name}) -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 -macro, zero otherwise. The argument @var{getc} is a function of type -@samp{int (*)(void)} which will return the next character in the input -stream, or EOF if no characters are left. The argument @var{ungetc} is -a function of type @samp{void (*)(int)} which will push a character back -into the input stream. The argument @var{name} is the word following -#pragma in the input stream. The input stream pointer will be pointing -just beyond the end of this word. The input stream should be left -undistrubed if the expression returns zero, otherwise it should be -pointing at the next character after the end of the pragma. Any -characters remaining on the line will be ignored. - -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 -compilers that do support @code{#pragma} for the sake of any user -programs which already use it. +@item REGISTER_TARGET_PRAGMAS (@var{pfile}) +Define this macro if you want to implement any target-specific pragmas. +If defined, it is a C expression which makes a series of calls to the +@code{cpp_register_pragma} and/or @code{cpp_register_pragma_space} +functions. The @var{pfile} argument is the first argument to supply to +these functions. The macro may also do setup required for the pragmas. + +The primary reason to define this macro is to provide compatibility with +other compilers for the same target. In general, we discourage +definition of target-specific pragmas for GCC. If the pragma can be implemented by atttributes then the macro @samp{INSERT_ATTRIBUTES} might be a useful one to define as well. -Note: older versions of this macro only had two arguments: @var{stream} -and @var{token}. The macro was changed in order to allow it to work -when gcc is built both with and without a cpp library. +Preprocessor macros that appear on pragma lines are not expanded. All +@samp{#pragma} directives that do not match any registered pragma are +silently ignored, unless the user specifies @samp{-Wunknown-pragmas}. + +@deftypefun void cpp_register_pragma (cpp_reader *@var{pfile}, const char *@var{space}, const char *@var{name}, void (*@var{callback}) (cpp_reader *)) + +Each call to @code{cpp_register_pragma} establishes one pragma. The +@var{callback} routine will be called when the preprocessor encounters a +pragma of the form + +@smallexample +#pragma [@var{space}] @var{name} @dots{} +@end smallexample + +@var{space} must have been the subject of a previous call to +@code{cpp_register_pragma_space}, or else be a null pointer. The +callback routine receives @var{pfile} as its first argument, but must +not use it for anything (this may change in the future). It may read +any text after the @var{name} by making calls to @code{c_lex}. Text +which is not read by the callback will be silently ignored. + +Note that both @var{space} and @var{name} are case sensitive. + +For an example use of this routine, see @file{c4x.h} and the callback +routines defined in @file{c4x.c}. +@end deftypefun + +@deftypefun void cpp_register_pragma_space (cpp_reader *@var{pfile}, const char *@var{space}) +This routine establishes a namespace for pragmas, which will be +registered by subsequent calls to @code{cpp_register_pragma}. For +example, pragmas defined by the C standard are in the @samp{STDC} +namespace, and pragmas specific to GCC are in the @samp{GCC} namespace. + +For an example use of this routine in a target header, see @file{v850.h}. +@end deftypefun @findex HANDLE_SYSV_PRAGMA @findex #pragma