Pass the correct number of parameters to `symbol_file_add'.
[deliverable/binutils-gdb.git] / gdb / expprint.c
CommitLineData
bd5635a1
RP
1/* Print in infix form a struct expression.
2 Copyright (C) 1986, 1989 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
10147c02 6This program is free software; you can redistribute it and/or modify
bd5635a1 7it under the terms of the GNU General Public License as published by
10147c02
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
bd5635a1 10
10147c02 11This program is distributed in the hope that it will be useful,
bd5635a1
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
10147c02
JG
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
bd5635a1
RP
19
20#include <stdio.h>
21#include "defs.h"
22#include "symtab.h"
23#include "param.h"
24#include "expression.h"
25#include "value.h"
26
27\f
28/* These codes indicate operator precedences, least tightly binding first. */
29/* Adding 1 to a precedence value is done for binary operators,
30 on the operand which is more tightly bound, so that operators
31 of equal precedence within that operand will get parentheses. */
32/* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
33 they are used as the "surrounding precedence" to force
34 various kinds of things to be parenthesized. */
35enum precedence
36{ PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_OR, PREC_AND,
37 PREC_LOGIOR, PREC_LOGAND, PREC_LOGXOR, PREC_EQUAL, PREC_ORDER,
38 PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
39 PREC_HYPER, PREC_PREFIX, PREC_SUFFIX };
40
41/* Table mapping opcodes into strings for printing operators
42 and precedences of the operators. */
43
44struct op_print
45{
46 char *string;
47 enum exp_opcode opcode;
48 /* Precedence of operator. These values are used only by comparisons. */
49 enum precedence precedence;
50 int right_assoc;
51};
52
81919cc8 53const static struct op_print op_print_tab[] =
bd5635a1
RP
54 {
55 {",", BINOP_COMMA, PREC_COMMA, 0},
56 {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
57 {"||", BINOP_OR, PREC_OR, 0},
58 {"&&", BINOP_AND, PREC_AND, 0},
59 {"|", BINOP_LOGIOR, PREC_LOGIOR, 0},
60 {"&", BINOP_LOGAND, PREC_LOGAND, 0},
61 {"^", BINOP_LOGXOR, PREC_LOGXOR, 0},
62 {"==", BINOP_EQUAL, PREC_EQUAL, 0},
63 {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
64 {"<=", BINOP_LEQ, PREC_ORDER, 0},
65 {">=", BINOP_GEQ, PREC_ORDER, 0},
66 {">", BINOP_GTR, PREC_ORDER, 0},
67 {"<", BINOP_LESS, PREC_ORDER, 0},
68 {">>", BINOP_RSH, PREC_SHIFT, 0},
69 {"<<", BINOP_LSH, PREC_SHIFT, 0},
70 {"+", BINOP_ADD, PREC_ADD, 0},
71 {"-", BINOP_SUB, PREC_ADD, 0},
72 {"*", BINOP_MUL, PREC_MUL, 0},
73 {"/", BINOP_DIV, PREC_MUL, 0},
74 {"%", BINOP_REM, PREC_MUL, 0},
75 {"@", BINOP_REPEAT, PREC_REPEAT, 0},
76 {"-", UNOP_NEG, PREC_PREFIX, 0},
77 {"!", UNOP_ZEROP, PREC_PREFIX, 0},
78 {"~", UNOP_LOGNOT, PREC_PREFIX, 0},
79 {"*", UNOP_IND, PREC_PREFIX, 0},
80 {"&", UNOP_ADDR, PREC_PREFIX, 0},
81 {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
82 {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
83 {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
84 /* C++ */
85 {"::", BINOP_SCOPE, PREC_PREFIX, 0},
86 };
87\f
88static void print_subexp ();
89
90void
91print_expression (exp, stream)
92 struct expression *exp;
93 FILE *stream;
94{
95 int pc = 0;
96 print_subexp (exp, &pc, stream, PREC_NULL);
97}
98
99/* Print the subexpression of EXP that starts in position POS, on STREAM.
100 PREC is the precedence of the surrounding operator;
101 if the precedence of the main operator of this subexpression is less,
102 parentheses are needed here. */
103
104static void
105print_subexp (exp, pos, stream, prec)
106 register struct expression *exp;
107 register int *pos;
108 FILE *stream;
109 enum precedence prec;
110{
111 register unsigned tem;
112 register int pc;
113 unsigned nargs;
114 register char *op_str;
115 int assign_modify = 0;
116 enum exp_opcode opcode;
117 enum precedence myprec;
118 /* Set to 1 for a right-associative operator. */
119 int assoc;
120
121 pc = (*pos)++;
122 opcode = exp->elts[pc].opcode;
123 switch (opcode)
124 {
125 case OP_SCOPE:
126 myprec = PREC_PREFIX;
127 assoc = 0;
128 (*pos) += 2;
10147c02
JG
129 print_subexp (exp, pos, stream,
130 (enum precedence) ((int) myprec + assoc));
131 fputs_filtered (" :: ", stream);
bd5635a1
RP
132 nargs = strlen (&exp->elts[pc + 2].string);
133 (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
134
10147c02 135 fputs_filtered (&exp->elts[pc + 2].string, stream);
bd5635a1
RP
136 return;
137
138 case OP_LONG:
139 (*pos) += 3;
140 value_print (value_from_long (exp->elts[pc + 1].type,
141 exp->elts[pc + 2].longconst),
142 stream, 0, Val_no_prettyprint);
143 return;
144
145 case OP_DOUBLE:
146 (*pos) += 3;
147 value_print (value_from_double (exp->elts[pc + 1].type,
148 exp->elts[pc + 2].doubleconst),
149 stream, 0, Val_no_prettyprint);
150 return;
151
152 case OP_VAR_VALUE:
153 (*pos) += 2;
10147c02 154 fputs_filtered (SYMBOL_NAME (exp->elts[pc + 1].symbol), stream);
bd5635a1
RP
155 return;
156
157 case OP_LAST:
158 (*pos) += 2;
10147c02
JG
159 fprintf_filtered (stream, "$%d",
160 longest_to_int (exp->elts[pc + 1].longconst));
bd5635a1
RP
161 return;
162
163 case OP_REGISTER:
164 (*pos) += 2;
10147c02
JG
165 fprintf_filtered (stream, "$%s",
166 longest_to_int (reg_names[exp->elts[pc + 1].longconst]));
bd5635a1
RP
167 return;
168
169 case OP_INTERNALVAR:
170 (*pos) += 2;
10147c02 171 fprintf_filtered (stream, "$%s",
bd5635a1
RP
172 internalvar_name (exp->elts[pc + 1].internalvar));
173 return;
174
175 case OP_FUNCALL:
176 (*pos) += 2;
10147c02 177 nargs = longest_to_int (exp->elts[pc + 1].longconst);
bd5635a1 178 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02 179 fputs_filtered (" (", stream);
bd5635a1
RP
180 for (tem = 0; tem < nargs; tem++)
181 {
182 if (tem != 0)
10147c02 183 fputs_filtered (", ", stream);
bd5635a1
RP
184 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
185 }
10147c02 186 fputs_filtered (")", stream);
bd5635a1
RP
187 return;
188
189 case OP_STRING:
190 nargs = strlen (&exp->elts[pc + 1].string);
191 (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
10147c02 192 fputs_filtered ("\"", stream);
bd5635a1
RP
193 for (tem = 0; tem < nargs; tem++)
194 printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
10147c02 195 fputs_filtered ("\"", stream);
bd5635a1
RP
196 return;
197
198 case TERNOP_COND:
199 if ((int) prec > (int) PREC_COMMA)
10147c02 200 fputs_filtered ("(", stream);
bd5635a1
RP
201 /* Print the subexpressions, forcing parentheses
202 around any binary operations within them.
203 This is more parentheses than are strictly necessary,
204 but it looks clearer. */
205 print_subexp (exp, pos, stream, PREC_HYPER);
10147c02 206 fputs_filtered (" ? ", stream);
bd5635a1 207 print_subexp (exp, pos, stream, PREC_HYPER);
10147c02 208 fputs_filtered (" : ", stream);
bd5635a1
RP
209 print_subexp (exp, pos, stream, PREC_HYPER);
210 if ((int) prec > (int) PREC_COMMA)
10147c02 211 fputs_filtered (")", stream);
bd5635a1
RP
212 return;
213
214 case STRUCTOP_STRUCT:
215 tem = strlen (&exp->elts[pc + 1].string);
216 (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
217 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02
JG
218 fputs_filtered (".", stream);
219 fputs_filtered (&exp->elts[pc + 1].string, stream);
bd5635a1
RP
220 return;
221
222 case STRUCTOP_PTR:
223 tem = strlen (&exp->elts[pc + 1].string);
224 (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
225 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02
JG
226 fputs_filtered ("->", stream);
227 fputs_filtered (&exp->elts[pc + 1].string, stream);
bd5635a1
RP
228 return;
229
230 case BINOP_SUBSCRIPT:
231 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02 232 fputs_filtered ("[", stream);
bd5635a1 233 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
10147c02 234 fputs_filtered ("]", stream);
bd5635a1
RP
235 return;
236
237 case UNOP_POSTINCREMENT:
238 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02 239 fputs_filtered ("++", stream);
bd5635a1
RP
240 return;
241
242 case UNOP_POSTDECREMENT:
243 print_subexp (exp, pos, stream, PREC_SUFFIX);
10147c02 244 fputs_filtered ("--", stream);
bd5635a1
RP
245 return;
246
247 case UNOP_CAST:
248 (*pos) += 2;
249 if ((int) prec > (int) PREC_PREFIX)
10147c02
JG
250 fputs_filtered ("(", stream);
251 fputs_filtered ("(", stream);
bd5635a1 252 type_print (exp->elts[pc + 1].type, "", stream, 0);
10147c02 253 fputs_filtered (") ", stream);
bd5635a1
RP
254 print_subexp (exp, pos, stream, PREC_PREFIX);
255 if ((int) prec > (int) PREC_PREFIX)
10147c02 256 fputs_filtered (")", stream);
bd5635a1
RP
257 return;
258
259 case UNOP_MEMVAL:
260 (*pos) += 2;
261 if ((int) prec > (int) PREC_PREFIX)
10147c02
JG
262 fputs_filtered ("(", stream);
263 fputs_filtered ("{", stream);
bd5635a1 264 type_print (exp->elts[pc + 1].type, "", stream, 0);
10147c02 265 fputs_filtered ("} ", stream);
bd5635a1
RP
266 print_subexp (exp, pos, stream, PREC_PREFIX);
267 if ((int) prec > (int) PREC_PREFIX)
10147c02 268 fputs_filtered (")", stream);
bd5635a1
RP
269 return;
270
271 case BINOP_ASSIGN_MODIFY:
272 opcode = exp->elts[pc + 1].opcode;
273 (*pos) += 2;
274 myprec = PREC_ASSIGN;
275 assoc = 1;
276 assign_modify = 1;
277 for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
278 if (op_print_tab[tem].opcode == opcode)
279 {
280 op_str = op_print_tab[tem].string;
281 break;
282 }
81919cc8 283 break;
bd5635a1
RP
284
285 case OP_THIS:
286 ++(*pos);
10147c02 287 fputs_filtered ("this", stream);
bd5635a1
RP
288 return;
289
290 default:
291 for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++)
292 if (op_print_tab[tem].opcode == opcode)
293 {
294 op_str = op_print_tab[tem].string;
295 myprec = op_print_tab[tem].precedence;
296 assoc = op_print_tab[tem].right_assoc;
297 break;
298 }
299 }
300
301 if ((int) myprec < (int) prec)
10147c02 302 fputs_filtered ("(", stream);
bd5635a1
RP
303 if ((int) opcode > (int) BINOP_END)
304 {
305 /* Unary prefix operator. */
10147c02 306 fputs_filtered (op_str, stream);
bd5635a1
RP
307 print_subexp (exp, pos, stream, PREC_PREFIX);
308 }
309 else
310 {
311 /* Binary operator. */
312 /* Print left operand.
313 If operator is right-associative,
314 increment precedence for this operand. */
10147c02
JG
315 print_subexp (exp, pos, stream,
316 (enum precedence) ((int) myprec + assoc));
bd5635a1
RP
317 /* Print the operator itself. */
318 if (assign_modify)
10147c02 319 fprintf_filtered (stream, " %s= ", op_str);
bd5635a1 320 else if (op_str[0] == ',')
10147c02 321 fprintf_filtered (stream, "%s ", op_str);
bd5635a1 322 else
10147c02 323 fprintf_filtered (stream, " %s ", op_str);
bd5635a1
RP
324 /* Print right operand.
325 If operator is left-associative,
326 increment precedence for this operand. */
10147c02
JG
327 print_subexp (exp, pos, stream,
328 (enum precedence) ((int) myprec + !assoc));
bd5635a1
RP
329 }
330 if ((int) myprec < (int) prec)
10147c02 331 fputs_filtered (")", stream);
bd5635a1 332}
This page took 0.067917 seconds and 4 git commands to generate.