]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/expprint.c
1 /* Print in infix form a struct expression.
2 Copyright (C) 1986, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
6 GDB 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 1, or (at your option)
11 GDB 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.
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include "expression.h"
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. */
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
};
41 /* Table mapping opcodes into strings for printing operators
42 and precedences of the operators. */
47 enum exp_opcode opcode
;
48 /* Precedence of operator. These values are used only by comparisons. */
49 enum precedence precedence
;
53 const static struct op_print op_print_tab
[] =
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},
85 {"::", BINOP_SCOPE
, PREC_PREFIX
, 0},
88 static void print_subexp ();
91 print_expression (exp
, stream
)
92 struct expression
*exp
;
96 print_subexp (exp
, &pc
, stream
, PREC_NULL
);
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. */
105 print_subexp (exp
, pos
, stream
, prec
)
106 register struct expression
*exp
;
109 enum precedence prec
;
111 register unsigned tem
;
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. */
122 opcode
= exp
->elts
[pc
].opcode
;
126 myprec
= PREC_PREFIX
;
129 print_subexp (exp
, pos
, stream
, (int) myprec
+ assoc
);
130 fprintf (stream
, " :: ");
131 nargs
= strlen (&exp
->elts
[pc
+ 2].string
);
132 (*pos
) += 1 + (nargs
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
134 fprintf (stream
, &exp
->elts
[pc
+ 2].string
);
139 value_print (value_from_long (exp
->elts
[pc
+ 1].type
,
140 exp
->elts
[pc
+ 2].longconst
),
141 stream
, 0, Val_no_prettyprint
);
146 value_print (value_from_double (exp
->elts
[pc
+ 1].type
,
147 exp
->elts
[pc
+ 2].doubleconst
),
148 stream
, 0, Val_no_prettyprint
);
153 fprintf (stream
, "%s", SYMBOL_NAME (exp
->elts
[pc
+ 1].symbol
));
158 fprintf (stream
, "$%d", (int) exp
->elts
[pc
+ 1].longconst
);
163 fprintf (stream
, "$%s", reg_names
[exp
->elts
[pc
+ 1].longconst
]);
168 fprintf (stream
, "$%s",
169 internalvar_name (exp
->elts
[pc
+ 1].internalvar
));
174 nargs
= exp
->elts
[pc
+ 1].longconst
;
175 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
176 fprintf (stream
, " (");
177 for (tem
= 0; tem
< nargs
; tem
++)
180 fprintf (stream
, ", ");
181 print_subexp (exp
, pos
, stream
, PREC_ABOVE_COMMA
);
183 fprintf (stream
, ")");
187 nargs
= strlen (&exp
->elts
[pc
+ 1].string
);
188 (*pos
) += 2 + (nargs
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
189 fprintf (stream
, "\"");
190 for (tem
= 0; tem
< nargs
; tem
++)
191 printchar ((&exp
->elts
[pc
+ 1].string
)[tem
], stream
, '"');
192 fprintf (stream
, "\"");
196 if ((int) prec
> (int) PREC_COMMA
)
197 fprintf (stream
, "(");
198 /* Print the subexpressions, forcing parentheses
199 around any binary operations within them.
200 This is more parentheses than are strictly necessary,
201 but it looks clearer. */
202 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
203 fprintf (stream
, " ? ");
204 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
205 fprintf (stream
, " : ");
206 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
207 if ((int) prec
> (int) PREC_COMMA
)
208 fprintf (stream
, ")");
211 case STRUCTOP_STRUCT
:
212 tem
= strlen (&exp
->elts
[pc
+ 1].string
);
213 (*pos
) += 2 + (tem
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
214 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
215 fprintf (stream
, ".%s", &exp
->elts
[pc
+ 1].string
);
219 tem
= strlen (&exp
->elts
[pc
+ 1].string
);
220 (*pos
) += 2 + (tem
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
221 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
222 fprintf (stream
, "->%s", &exp
->elts
[pc
+ 1].string
);
225 case BINOP_SUBSCRIPT
:
226 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
227 fprintf (stream
, "[");
228 print_subexp (exp
, pos
, stream
, PREC_ABOVE_COMMA
);
229 fprintf (stream
, "]");
232 case UNOP_POSTINCREMENT
:
233 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
234 fprintf (stream
, "++");
237 case UNOP_POSTDECREMENT
:
238 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
239 fprintf (stream
, "--");
244 if ((int) prec
> (int) PREC_PREFIX
)
245 fprintf (stream
, "(");
246 fprintf (stream
, "(");
247 type_print (exp
->elts
[pc
+ 1].type
, "", stream
, 0);
248 fprintf (stream
, ") ");
249 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
250 if ((int) prec
> (int) PREC_PREFIX
)
251 fprintf (stream
, ")");
256 if ((int) prec
> (int) PREC_PREFIX
)
257 fprintf (stream
, "(");
258 fprintf (stream
, "{");
259 type_print (exp
->elts
[pc
+ 1].type
, "", stream
, 0);
260 fprintf (stream
, "} ");
261 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
262 if ((int) prec
> (int) PREC_PREFIX
)
263 fprintf (stream
, ")");
266 case BINOP_ASSIGN_MODIFY
:
267 opcode
= exp
->elts
[pc
+ 1].opcode
;
269 myprec
= PREC_ASSIGN
;
272 for (tem
= 0; tem
< sizeof op_print_tab
/ sizeof op_print_tab
[0]; tem
++)
273 if (op_print_tab
[tem
].opcode
== opcode
)
275 op_str
= op_print_tab
[tem
].string
;
282 fprintf (stream
, "this");
286 for (tem
= 0; tem
< sizeof op_print_tab
/ sizeof op_print_tab
[0]; tem
++)
287 if (op_print_tab
[tem
].opcode
== opcode
)
289 op_str
= op_print_tab
[tem
].string
;
290 myprec
= op_print_tab
[tem
].precedence
;
291 assoc
= op_print_tab
[tem
].right_assoc
;
296 if ((int) myprec
< (int) prec
)
297 fprintf (stream
, "(");
298 if ((int) opcode
> (int) BINOP_END
)
300 /* Unary prefix operator. */
301 fprintf (stream
, "%s", op_str
);
302 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
306 /* Binary operator. */
307 /* Print left operand.
308 If operator is right-associative,
309 increment precedence for this operand. */
310 print_subexp (exp
, pos
, stream
, (int) myprec
+ assoc
);
311 /* Print the operator itself. */
313 fprintf (stream
, " %s= ", op_str
);
314 else if (op_str
[0] == ',')
315 fprintf (stream
, "%s ", op_str
);
317 fprintf (stream
, " %s ", op_str
);
318 /* Print right operand.
319 If operator is left-associative,
320 increment precedence for this operand. */
321 print_subexp (exp
, pos
, stream
, (int) myprec
+ !assoc
);
323 if ((int) myprec
< (int) prec
)
324 fprintf (stream
, ")");