OSDN Git Service

(const_binop, fold_convert, fold):
[pf3gnuchains/gcc-fork.git] / gcc / c-pragma.c
1 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
2    Copyright (C) 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <stdio.h>
21 #include "config.h"
22 #include "tree.h"
23
24 #ifdef HANDLE_SYSV_PRAGMA
25
26 /* Support #pragma weak by default if WEAK_ASM_OP is defined.  */
27 #if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (SET_ASM_OP)
28 #define HANDLE_PRAGMA_WEAK 1
29 #endif
30
31 /* When structure field packing is in effect, this variable is the
32    number of bits to use as the maximum alignment.  When packing is not
33    in effect, this is zero. */
34
35 extern int maximum_field_alignment;
36
37 /* File used for outputting assembler code.  */
38 extern FILE *asm_out_file;
39
40 /* Handle one token of a pragma directive.  TOKEN is the
41    current token, and STRING is its printable form.  */
42
43 void
44 handle_pragma_token (string, token)
45      char *string;
46      tree token;
47 {
48   static enum pragma_state
49     {
50       ps_start,
51       ps_done,
52       ps_bad,
53       ps_weak,
54       ps_name,
55       ps_equals,
56       ps_value,
57       ps_pack,
58       ps_left,
59       ps_align,
60       ps_right
61       } state = ps_start, type;
62   static char *name;
63   static char *value;
64   static int align;
65
66   if (string == 0)
67     {
68       if (type == ps_pack)
69         {
70           if (state == ps_right)
71             maximum_field_alignment = align * 8;
72           else
73             warning ("malformed `#pragma pack'");
74         }
75       else if (type == ps_weak)
76         {
77 #ifdef HANDLE_PRAGMA_WEAK
78           if (HANDLE_PRAGMA_WEAK)
79             {
80               if (state == ps_name || state == ps_value)
81                 {
82                   fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
83                   ASM_OUTPUT_LABELREF (asm_out_file, name);
84                   fputc ('\n', asm_out_file);
85                   if (state == ps_value)
86                     {
87                       fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
88                       ASM_OUTPUT_LABELREF (asm_out_file, name);
89                       fputc (',', asm_out_file);
90                       ASM_OUTPUT_LABELREF (asm_out_file, value);
91                       fputc ('\n', asm_out_file);
92                     }
93                 }
94               else if (! (state == ps_done || state == ps_start))
95                 warning ("malformed `#pragma weak'");
96             }
97 #endif /* HANDLE_PRAMA_WEAK */
98         }
99
100       type = state = ps_start;
101       return;
102     }
103
104   switch (state)
105     {
106     case ps_start:
107       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
108         {
109           if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
110             type = state = ps_pack;
111           else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
112             type = state = ps_weak;
113           else
114             type = state = ps_done;
115         }
116       else
117         type = state = ps_done;
118       break;
119
120     case ps_weak:
121       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
122         {
123           name = IDENTIFIER_POINTER (token);
124           state = ps_name;
125         }
126       else
127         state = ps_bad;
128       break;
129
130     case ps_name:
131       state = (strcmp (string, "=") ? ps_bad : ps_equals);
132       break;
133
134     case ps_equals:
135       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
136         {
137           value = IDENTIFIER_POINTER (token);
138           state = ps_value;
139         }
140       else
141         state = ps_bad;
142       break;
143
144     case ps_value:
145       state = ps_bad;
146       break;
147
148     case ps_pack:
149       if (strcmp (string, "(") == 0)
150         state = ps_left;
151       else
152         state = ps_bad;
153       break;
154
155     case ps_left:
156       if (token && TREE_CODE (token) == INTEGER_CST
157           && TREE_INT_CST_HIGH (token) == 0)
158         switch (TREE_INT_CST_LOW (token))
159           {
160           case 1:
161           case 2:
162           case 4:
163             align = TREE_INT_CST_LOW (token);
164             state = ps_align;
165             break;
166
167           default:
168             state = ps_bad;
169           }
170       else if (! token && strcmp (string, ")") == 0)
171         {
172           align = 0;
173           state = ps_right;
174         }
175       else
176         state = ps_bad;
177       break;
178
179     case ps_align:
180       if (strcmp (string, ")") == 0)
181         state = ps_right;
182       else
183         state = ps_bad;
184       break;
185
186     case ps_right:
187       state = ps_bad;
188       break;
189
190     case ps_bad:
191     case ps_done:
192       break;
193
194     default:
195       abort ();
196     }
197 }
198 #endif /* HANDLE_SYSV_PRAGMA */