]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/expprint.c
1 /* Print in infix form a struct expression.
2 Copyright (C) 1986 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
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 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
;
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
),
146 value_print (value_from_double (exp
->elts
[pc
+ 1].type
,
147 exp
->elts
[pc
+ 2].doubleconst
),
153 fprintf (stream
, "%s", SYMBOL_NAME (exp
->elts
[pc
+ 1].symbol
));
158 fprintf (stream
, "$%d", 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
;
280 for (tem
= 0; tem
< sizeof op_print_tab
/ sizeof op_print_tab
[0]; tem
++)
281 if (op_print_tab
[tem
].opcode
== opcode
)
283 op_str
= op_print_tab
[tem
].string
;
284 myprec
= op_print_tab
[tem
].precedence
;
285 assoc
= op_print_tab
[tem
].right_assoc
;
290 if ((int) myprec
< (int) prec
)
291 fprintf (stream
, "(");
292 if ((int) opcode
> (int) BINOP_END
)
294 /* Unary prefix operator. */
295 fprintf (stream
, "%s", op_str
);
296 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
300 /* Binary operator. */
301 /* Print left operand.
302 If operator is right-associative,
303 increment precedence for this operand. */
304 print_subexp (exp
, pos
, stream
, (int) myprec
+ assoc
);
305 /* Print the operator itself. */
307 fprintf (stream
, " %s= ", op_str
);
308 else if (op_str
[0] == ',')
309 fprintf (stream
, "%s ", op_str
);
311 fprintf (stream
, " %s ", op_str
);
312 /* Print right operand.
313 If operator is left-associative,
314 increment precedence for this operand. */
315 print_subexp (exp
, pos
, stream
, (int) myprec
+ !assoc
);
317 if ((int) myprec
< (int) prec
)
318 fprintf (stream
, ")");