home *** CD-ROM | disk | FTP | other *** search
- /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This file is part of GNU CC.
-
- GNU CC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include <stdio.h>
- #include "config.h"
- #include "tree.h"
-
- #ifdef HANDLE_SYSV_PRAGMA
-
- /* Support #pragma weak by default if WEAK_ASM_OP is defined. */
- #if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (SET_ASM_OP)
- #define HANDLE_PRAGMA_WEAK 1
- #endif
-
- /* When structure field packing is in effect, this variable is the
- number of bits to use as the maximum alignment. When packing is not
- in effect, this is zero. */
-
- 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;
- {
- static enum pragma_state
- {
- ps_start,
- ps_done,
- ps_bad,
- ps_weak,
- ps_name,
- ps_equals,
- ps_value,
- ps_pack,
- ps_left,
- ps_align,
- ps_right
- } state = ps_start, type;
- static char *name;
- 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)
- {
- if (state == ps_name || state == ps_value)
- {
- fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
- ASM_OUTPUT_LABELREF (asm_out_file, name);
- fputc ('\n', asm_out_file);
- if (state == ps_value)
- {
- fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
- ASM_OUTPUT_LABELREF (asm_out_file, name);
- fputc (',', asm_out_file);
- ASM_OUTPUT_LABELREF (asm_out_file, value);
- fputc ('\n', asm_out_file);
- }
- }
- else if (! (state == ps_done || state == ps_start))
- warning ("malformed `#pragma weak'");
- }
- #endif /* HANDLE_PRAMA_WEAK */
- }
-
- type = state = ps_start;
- return;
- }
-
- switch (state)
- {
- case ps_start:
- if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- {
- 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;
- }
- else
- type = state = ps_done;
- break;
-
- case ps_weak:
- if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- {
- name = IDENTIFIER_POINTER (token);
- state = ps_name;
- }
- else
- state = ps_bad;
- break;
-
- case ps_name:
- state = (strcmp (string, "=") ? ps_bad : ps_equals);
- break;
-
- case ps_equals:
- if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- {
- value = IDENTIFIER_POINTER (token);
- state = ps_value;
- }
- else
- state = ps_bad;
- break;
-
- case ps_value:
- state = ps_bad;
- break;
-
- case ps_pack:
- if (strcmp (string, "(") == 0)
- state = ps_left;
- else
- state = ps_bad;
- break;
-
- case ps_left:
- if (token && TREE_CODE (token) == INTEGER_CST
- && TREE_INT_CST_HIGH (token) == 0)
- switch (TREE_INT_CST_LOW (token))
- {
- case 1:
- case 2:
- case 4:
- align = TREE_INT_CST_LOW (token);
- state = ps_align;
- break;
-
- default:
- state = ps_bad;
- }
- else if (! token && strcmp (string, ")") == 0)
- {
- align = 0;
- state = ps_right;
- }
- else
- state = ps_bad;
- break;
-
- case ps_align:
- if (strcmp (string, ")") == 0)
- state = ps_right;
- else
- state = ps_bad;
- break;
-
- case ps_right:
- state = ps_bad;
- break;
-
- case ps_bad:
- case ps_done:
- break;
-
- default:
- abort ();
- }
- }
- #endif /* HANDLE_SYSV_PRAGMA */
-
- int parameter_pragma_supplied = 0;
-
- #ifdef SPECIAL_CALLING_CONVENTIONS
- SPECIAL_CALLING_CONVENTIONS current_call_convention;
- #endif
-
- char current_name_in_pragma[1000];
-
- #ifdef HANDLE_MPW_PRAGMA
-
- /* 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;
- {
- /* This enum defines all the states that our miniature pragma parser
- can be in. */
- static enum pragma_state
- {
- ps_start,
- ps_parameter,
- ps_parameter_result,
- ps_parameter_function,
- ps_parameter_open,
- ps_parameter_arg,
- ps_parameter_comma,
- ps_parameter_close,
- ps_trace,
- ps_done,
- ps_bad
- } state = ps_start, type;
- static int nextreg;
- extern int flag_gen_trace_calls, flag_trace_pragma_override;
- int i, regn;
-
- /* Handle the case of a empty token string, which is what we get
- here when the pragma reader is at the end of the line. */
- if (string == 0)
- {
- switch (type)
- {
- case ps_parameter:
- if (state == ps_parameter_close)
- parameter_pragma_supplied = 1;
- else if (state == ps_parameter_function)
- parameter_pragma_supplied = 1;
- else
- warning ("malformed `#pragma parameter'");
- break;
- }
-
- /* Reset the type and state for the next pragma. */
- type = state = ps_start;
- return;
- }
-
- /* printf("String is %s, type is %d, state is %d\n", string, type, state); */
-
- switch (state)
- {
- case ps_start:
- if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- {
- if (strcmp (IDENTIFIER_POINTER (token), "dump") == 0)
- {
- warning ("Don't know how to dump precompiled info");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "force_active") == 0)
- {
- warning ("Don't know how to dump precompiled info");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "load") == 0)
- {
- warning ("Don't know how to load precompiled info");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "mbg") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "opt") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "parameter") == 0)
- {
- /* Reset the contents of the pragma we're working on. */
- #ifdef SPECIAL_CALLING_CONVENTIONS
- /* (should be attached to the target machine better) */
- current_call_convention.pascalp = 0;
- current_call_convention.return_regno = -1;
- for (i = 0; i < 5; ++i)
- current_call_convention.parameter_regno[i] = -1;
- #endif
- strcpy (current_name_in_pragma, "");
- type = state = ps_parameter;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "pop") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "processor") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "push") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "trace") == 0)
- {
- type = state = (flag_trace_pragma_override ? ps_done : ps_trace);
- }
- else if (strcmp (IDENTIFIER_POINTER (token), "warnings") == 0)
- {
- warning ("unimplemented pragma");
- type = state = ps_done;
- }
- else
- /* This is a pragma we don't understand. Don't complain
- though, just ignore it and get out of here. */
- type = state = ps_done;
- }
- else
- type = state = ps_done;
- break;
-
- case ps_parameter:
- if ((regn = parsereg (string)) >= 0)
- {
- #ifdef SPECIAL_CALLING_CONVENTIONS
- current_call_convention.return_regno = regn;
- #endif
- state = ps_parameter_result;
- }
- else
- {
- strcpy(current_name_in_pragma, string);
- state = ps_parameter_function;
- }
- break;
-
- case ps_parameter_result:
- strcpy(current_name_in_pragma, string);
- state = ps_parameter_function;
- break;
-
- case ps_parameter_function:
- if (strcmp (string, "(") == 0)
- state = ps_parameter_open;
- else
- state = ps_bad;
- break;
-
- case ps_parameter_open:
- nextreg = 0;
- case ps_parameter_comma:
- #ifdef SPECIAL_CALLING_CONVENTIONS
- if ((regn = parsereg (string)) >= 0)
- {
- current_call_convention.parameter_regno[nextreg++] = regn;
- state = ps_parameter_arg;
- }
- else
- #endif
- state = ps_bad;
- break;
-
- case ps_parameter_arg:
- if (strcmp (string, ")") == 0)
- state = ps_parameter_close;
- else if (strcmp (string, ",") == 0)
- state = ps_parameter_comma;
- else
- state = ps_bad;
- break;
-
- case ps_parameter_close:
- /* If we get here, then there was junk after the closing paren. */
- state = ps_bad;
- break;
-
- case ps_trace:
- if (strcmp (string, "on") == 0)
- flag_gen_trace_calls = 1;
- else if (strcmp (string, "off") == 0)
- flag_gen_trace_calls = 0;
- else
- state = ps_bad;
- break;
-
- case ps_done:
- case ps_bad:
- break;
-
- default:
- abort ();
- }
- }
-
- #endif /* HANDLE_MPW_PRAGMA */
-