]>
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!
23 #include "expression.h"
27 /* These codes indicate operator precedences, least tightly binding first. */
28 /* Adding 1 to a precedence value is done for binary operators,
29 on the operand which is more tightly bound, so that operators
30 of equal precedence within that operand will get parentheses. */
31 /* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
32 they are used as the "surrounding precedence" to force
33 various kinds of things to be parenthesized. */
35 { PREC_NULL
, PREC_COMMA
, PREC_ABOVE_COMMA
, PREC_ASSIGN
, PREC_OR
, PREC_AND
,
36 PREC_LOGIOR
, PREC_LOGAND
, PREC_LOGXOR
, PREC_EQUAL
, PREC_ORDER
,
37 PREC_SHIFT
, PREC_ADD
, PREC_MUL
, PREC_REPEAT
,
38 PREC_HYPER
, PREC_PREFIX
, PREC_SUFFIX
};
40 /* Table mapping opcodes into strings for printing operators
41 and precedences of the operators. */
46 enum exp_opcode opcode
;
47 /* Precedence of operator. These values are used only by comparisons. */
48 enum precedence precedence
;
52 static struct op_print op_print_tab
[] =
54 {",", BINOP_COMMA
, PREC_COMMA
, 0},
55 {"=", BINOP_ASSIGN
, PREC_ASSIGN
, 1},
56 {"||", BINOP_OR
, PREC_OR
, 0},
57 {"&&", BINOP_AND
, PREC_AND
, 0},
58 {"|", BINOP_LOGIOR
, PREC_LOGIOR
, 0},
59 {"&", BINOP_LOGAND
, PREC_LOGAND
, 0},
60 {"^", BINOP_LOGXOR
, PREC_LOGXOR
, 0},
61 {"==", BINOP_EQUAL
, PREC_EQUAL
, 0},
62 {"!=", BINOP_NOTEQUAL
, PREC_EQUAL
, 0},
63 {"<=", BINOP_LEQ
, PREC_ORDER
, 0},
64 {">=", BINOP_GEQ
, PREC_ORDER
, 0},
65 {">", BINOP_GTR
, PREC_ORDER
, 0},
66 {"<", BINOP_LESS
, PREC_ORDER
, 0},
67 {">>", BINOP_RSH
, PREC_SHIFT
, 0},
68 {"<<", BINOP_LSH
, PREC_SHIFT
, 0},
69 {"+", BINOP_ADD
, PREC_ADD
, 0},
70 {"-", BINOP_SUB
, PREC_ADD
, 0},
71 {"*", BINOP_MUL
, PREC_MUL
, 0},
72 {"/", BINOP_DIV
, PREC_MUL
, 0},
73 {"%", BINOP_REM
, PREC_MUL
, 0},
74 {"@", BINOP_REPEAT
, PREC_REPEAT
, 0},
75 {"-", UNOP_NEG
, PREC_PREFIX
, 0},
76 {"!", UNOP_ZEROP
, PREC_PREFIX
, 0},
77 {"~", UNOP_LOGNOT
, PREC_PREFIX
, 0},
78 {"*", UNOP_IND
, PREC_PREFIX
, 0},
79 {"&", UNOP_ADDR
, PREC_PREFIX
, 0},
80 {"sizeof ", UNOP_SIZEOF
, PREC_PREFIX
, 0},
81 {"++", UNOP_PREINCREMENT
, PREC_PREFIX
, 0},
82 {"--", UNOP_PREDECREMENT
, PREC_PREFIX
, 0},
84 {"::", BINOP_SCOPE
, PREC_PREFIX
, 0},
87 static void print_subexp ();
90 print_expression (exp
, stream
)
91 struct expression
*exp
;
95 print_subexp (exp
, &pc
, stream
, PREC_NULL
);
98 /* Print the subexpression of EXP that starts in position POS, on STREAM.
99 PREC is the precedence of the surrounding operator;
100 if the precedence of the main operator of this subexpression is less,
101 parentheses are needed here. */
104 print_subexp (exp
, pos
, stream
, prec
)
105 register struct expression
*exp
;
108 enum precedence prec
;
113 register char *op_str
;
114 int assign_modify
= 0;
115 enum exp_opcode opcode
;
116 enum precedence myprec
;
117 /* Set to 1 for a right-associative operator. */
121 opcode
= exp
->elts
[pc
].opcode
;
125 myprec
= PREC_PREFIX
;
128 print_subexp (exp
, pos
, stream
, (int) myprec
+ assoc
);
129 fprintf (stream
, " :: ");
130 nargs
= strlen (&exp
->elts
[pc
+ 2].string
);
131 (*pos
) += 1 + (nargs
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
133 fprintf (stream
, &exp
->elts
[pc
+ 2].string
);
138 value_print (value_from_long (exp
->elts
[pc
+ 1].type
,
139 exp
->elts
[pc
+ 2].longconst
),
145 value_print (value_from_double (exp
->elts
[pc
+ 1].type
,
146 exp
->elts
[pc
+ 2].doubleconst
),
152 fprintf (stream
, "%s", SYMBOL_NAME (exp
->elts
[pc
+ 1].symbol
));
157 fprintf (stream
, "$%d", exp
->elts
[pc
+ 1].longconst
);
162 fprintf (stream
, "$%s", reg_names
[exp
->elts
[pc
+ 1].longconst
]);
167 fprintf (stream
, "$%s",
168 internalvar_name (exp
->elts
[pc
+ 1].internalvar
));
173 nargs
= exp
->elts
[pc
+ 1].longconst
;
174 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
175 fprintf (stream
, " (");
176 for (tem
= 0; tem
< nargs
; tem
++)
179 fprintf (stream
, ", ");
180 print_subexp (exp
, pos
, stream
, PREC_ABOVE_COMMA
);
182 fprintf (stream
, ")");
186 nargs
= strlen (&exp
->elts
[pc
+ 1].string
);
187 (*pos
) += 2 + (nargs
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
188 fprintf (stream
, "\"");
189 for (tem
= 0; tem
< nargs
; tem
++)
190 printchar ((&exp
->elts
[pc
+ 1].string
)[tem
], stream
);
191 fprintf (stream
, "\"");
195 if ((int) prec
> (int) PREC_COMMA
)
196 fprintf (stream
, "(");
197 /* Print the subexpressions, forcing parentheses
198 around any binary operations within them.
199 This is more parentheses than are strictly necessary,
200 but it looks clearer. */
201 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
202 fprintf (stream
, " ? ");
203 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
204 fprintf (stream
, " : ");
205 print_subexp (exp
, pos
, stream
, PREC_HYPER
);
206 if ((int) prec
> (int) PREC_COMMA
)
207 fprintf (stream
, ")");
210 case STRUCTOP_STRUCT
:
211 tem
= strlen (&exp
->elts
[pc
+ 1].string
);
212 (*pos
) += 2 + (tem
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
213 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
214 fprintf (stream
, ".%s", &exp
->elts
[pc
+ 1].string
);
218 tem
= strlen (&exp
->elts
[pc
+ 1].string
);
219 (*pos
) += 2 + (tem
+ sizeof (union exp_element
)) / sizeof (union exp_element
);
220 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
221 fprintf (stream
, "->%s", &exp
->elts
[pc
+ 1].string
);
224 case BINOP_SUBSCRIPT
:
225 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
226 fprintf (stream
, "[");
227 print_subexp (exp
, pos
, stream
, PREC_ABOVE_COMMA
);
228 fprintf (stream
, "]");
231 case UNOP_POSTINCREMENT
:
232 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
233 fprintf (stream
, "++");
236 case UNOP_POSTDECREMENT
:
237 print_subexp (exp
, pos
, stream
, PREC_SUFFIX
);
238 fprintf (stream
, "--");
243 if ((int) prec
> (int) PREC_PREFIX
)
244 fprintf (stream
, "(");
245 fprintf (stream
, "(");
246 type_print (exp
->elts
[pc
+ 1].type
, "", stream
, 0);
247 fprintf (stream
, ") ");
248 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
249 if ((int) prec
> (int) PREC_PREFIX
)
250 fprintf (stream
, ")");
255 if ((int) prec
> (int) PREC_PREFIX
)
256 fprintf (stream
, "(");
257 fprintf (stream
, "{");
258 type_print (exp
->elts
[pc
+ 1].type
, "", stream
, 0);
259 fprintf (stream
, "} ");
260 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
261 if ((int) prec
> (int) PREC_PREFIX
)
262 fprintf (stream
, ")");
265 case BINOP_ASSIGN_MODIFY
:
266 opcode
= exp
->elts
[pc
+ 1].opcode
;
268 myprec
= PREC_ASSIGN
;
271 for (tem
= 0; tem
< sizeof op_print_tab
/ sizeof op_print_tab
[0]; tem
++)
272 if (op_print_tab
[tem
].opcode
== opcode
)
274 op_str
= op_print_tab
[tem
].string
;
279 for (tem
= 0; tem
< sizeof op_print_tab
/ sizeof op_print_tab
[0]; tem
++)
280 if (op_print_tab
[tem
].opcode
== opcode
)
282 op_str
= op_print_tab
[tem
].string
;
283 myprec
= op_print_tab
[tem
].precedence
;
284 assoc
= op_print_tab
[tem
].right_assoc
;
289 if ((int) myprec
< (int) prec
)
290 fprintf (stream
, "(");
291 if ((int) opcode
> (int) BINOP_END
)
293 /* Unary prefix operator. */
294 fprintf (stream
, "%s", op_str
);
295 print_subexp (exp
, pos
, stream
, PREC_PREFIX
);
299 /* Binary operator. */
300 /* Print left operand.
301 If operator is right-associative,
302 increment precedence for this operand. */
303 print_subexp (exp
, pos
, stream
, (int) myprec
+ assoc
);
304 /* Print the operator itself. */
306 fprintf (stream
, " %s= ", op_str
);
307 else if (op_str
[0] == ',')
308 fprintf (stream
, "%s ", op_str
);
310 fprintf (stream
, " %s ", op_str
);
311 /* Print right operand.
312 If operator is left-associative,
313 increment precedence for this operand. */
314 print_subexp (exp
, pos
, stream
, (int) myprec
+ !assoc
);
316 if ((int) myprec
< (int) prec
)
317 fprintf (stream
, ")");