Remove per-language op_name functions
[deliverable/binutils-gdb.git] / gdb / expprint.c
CommitLineData
c906108c 1/* Print in infix form a struct expression.
1bac305b 2
b811d2c2 3 Copyright (C) 1986-2020 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
4de283e4 21#include "symtab.h"
d55e5aa6 22#include "gdbtypes.h"
4de283e4
TT
23#include "expression.h"
24#include "value.h"
c906108c
SS
25#include "language.h"
26#include "parser-defs.h"
4de283e4 27#include "user-regs.h" /* For user_reg_map_regnum_to_name. */
82eeeb94 28#include "target.h"
4de283e4
TT
29#include "block.h"
30#include "objfiles.h"
79a45b7d 31#include "valprint.h"
7f6aba03 32#include "cli/cli-style.h"
4de283e4
TT
33
34#include <ctype.h>
c906108c 35
c906108c 36void
fba45db2 37print_expression (struct expression *exp, struct ui_file *stream)
c906108c
SS
38{
39 int pc = 0;
d7f9d729 40
c906108c
SS
41 print_subexp (exp, &pc, stream, PREC_NULL);
42}
43
44/* Print the subexpression of EXP that starts in position POS, on STREAM.
45 PREC is the precedence of the surrounding operator;
46 if the precedence of the main operator of this subexpression is less,
47 parentheses are needed here. */
48
5f9769d1 49void
f86f5ca3 50print_subexp (struct expression *exp, int *pos,
fba45db2 51 struct ui_file *stream, enum precedence prec)
5f9769d1 52{
5aba6ebe
AB
53 exp->language_defn->expression_ops ()->print_subexp (exp, pos, stream,
54 prec);
5f9769d1
PH
55}
56
6d816919
AB
57/* See parser-defs.h. */
58
59void
60print_subexp_funcall (struct expression *exp, int *pos,
61 struct ui_file *stream)
62{
6d816919 63 unsigned nargs = longest_to_int (exp->elts[*pos].longconst);
86775fab 64 (*pos) += 2;
6d816919
AB
65 print_subexp (exp, pos, stream, PREC_SUFFIX);
66 fputs_filtered (" (", stream);
67 for (unsigned tem = 0; tem < nargs; tem++)
68 {
69 if (tem != 0)
70 fputs_filtered (", ", stream);
71 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
72 }
73 fputs_filtered (")", stream);
74}
75
5f9769d1
PH
76/* Standard implementation of print_subexp for use in language_defn
77 vectors. */
78void
79print_subexp_standard (struct expression *exp, int *pos,
80 struct ui_file *stream, enum precedence prec)
c906108c 81{
f86f5ca3
PH
82 unsigned tem;
83 const struct op_print *op_print_tab;
84 int pc;
c906108c 85 unsigned nargs;
a121b7c1 86 const char *op_str;
c906108c
SS
87 int assign_modify = 0;
88 enum exp_opcode opcode;
89 enum precedence myprec = PREC_NULL;
90 /* Set to 1 for a right-associative operator. */
91 int assoc = 0;
3d6d86c6 92 struct value *val;
c906108c
SS
93 char *tempstr = NULL;
94
b7c6e27d 95 op_print_tab = exp->language_defn->opcode_print_table ();
c906108c
SS
96 pc = (*pos)++;
97 opcode = exp->elts[pc].opcode;
98 switch (opcode)
99 {
c5aa993b 100 /* Common ops */
c906108c 101
4f485ebc
DE
102 case OP_TYPE:
103 (*pos) += 2;
104 type_print (exp->elts[pc + 1].type, "", stream, 0);
105 return;
106
c906108c
SS
107 case OP_SCOPE:
108 myprec = PREC_PREFIX;
109 assoc = 0;
7d93a1e0 110 fputs_filtered (exp->elts[pc + 1].type->name (), stream);
c906108c
SS
111 fputs_filtered ("::", stream);
112 nargs = longest_to_int (exp->elts[pc + 2].longconst);
113 (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1);
114 fputs_filtered (&exp->elts[pc + 3].string, stream);
115 return;
116
117 case OP_LONG:
79a45b7d
TT
118 {
119 struct value_print_options opts;
d7f9d729 120
2a998fc0 121 get_no_prettyformat_print_options (&opts);
79a45b7d
TT
122 (*pos) += 3;
123 value_print (value_from_longest (exp->elts[pc + 1].type,
124 exp->elts[pc + 2].longconst),
125 stream, &opts);
126 }
c906108c
SS
127 return;
128
edd079d9 129 case OP_FLOAT:
79a45b7d
TT
130 {
131 struct value_print_options opts;
d7f9d729 132
2a998fc0 133 get_no_prettyformat_print_options (&opts);
79a45b7d 134 (*pos) += 3;
edd079d9
UW
135 value_print (value_from_contents (exp->elts[pc + 1].type,
136 exp->elts[pc + 2].floatconst),
79a45b7d
TT
137 stream, &opts);
138 }
c906108c
SS
139 return;
140
141 case OP_VAR_VALUE:
142 {
270140bd 143 const struct block *b;
d7f9d729 144
c906108c
SS
145 (*pos) += 3;
146 b = exp->elts[pc + 1].block;
147 if (b != NULL
148 && BLOCK_FUNCTION (b) != NULL
987012b8 149 && BLOCK_FUNCTION (b)->print_name () != NULL)
c906108c 150 {
987012b8 151 fputs_filtered (BLOCK_FUNCTION (b)->print_name (), stream);
c906108c
SS
152 fputs_filtered ("::", stream);
153 }
987012b8 154 fputs_filtered (exp->elts[pc + 2].symbol->print_name (), stream);
c906108c
SS
155 }
156 return;
157
74ea4be4
PA
158 case OP_VAR_MSYM_VALUE:
159 {
160 (*pos) += 3;
c9d95fa3 161 fputs_filtered (exp->elts[pc + 2].msymbol->print_name (), stream);
74ea4be4
PA
162 }
163 return;
164
858be34c
PA
165 case OP_FUNC_STATIC_VAR:
166 {
167 tem = longest_to_int (exp->elts[pc + 1].longconst);
168 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
169 fputs_filtered (&exp->elts[pc + 1].string, stream);
170 }
171 return;
172
36b11add
JK
173 case OP_VAR_ENTRY_VALUE:
174 {
36b11add
JK
175 (*pos) += 2;
176 fprintf_filtered (stream, "%s@entry",
987012b8 177 exp->elts[pc + 1].symbol->print_name ());
36b11add
JK
178 }
179 return;
180
c906108c
SS
181 case OP_LAST:
182 (*pos) += 2;
183 fprintf_filtered (stream, "$%d",
184 longest_to_int (exp->elts[pc + 1].longconst));
185 return;
186
187 case OP_REGISTER:
e36180d7 188 {
67f3407f 189 const char *name = &exp->elts[pc + 2].string;
d7f9d729 190
67f3407f 191 (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
eb8bc282 192 fprintf_filtered (stream, "$%s", name);
e36180d7
AC
193 return;
194 }
c906108c
SS
195
196 case OP_BOOL:
197 (*pos) += 2;
198 fprintf_filtered (stream, "%s",
199 longest_to_int (exp->elts[pc + 1].longconst)
200 ? "TRUE" : "FALSE");
201 return;
202
203 case OP_INTERNALVAR:
204 (*pos) += 2;
205 fprintf_filtered (stream, "$%s",
c5aa993b 206 internalvar_name (exp->elts[pc + 1].internalvar));
c906108c
SS
207 return;
208
209 case OP_FUNCALL:
6d816919 210 print_subexp_funcall (exp, pos, stream);
c906108c
SS
211 return;
212
213 case OP_NAME:
c5aa993b 214 nargs = longest_to_int (exp->elts[pc + 1].longconst);
c906108c
SS
215 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
216 fputs_filtered (&exp->elts[pc + 2].string, stream);
217 return;
218
219 case OP_STRING:
79a45b7d
TT
220 {
221 struct value_print_options opts;
d7f9d729 222
79a45b7d
TT
223 nargs = longest_to_int (exp->elts[pc + 1].longconst);
224 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
225 /* LA_PRINT_STRING will print using the current repeat count threshold.
226 If necessary, we can temporarily set it to zero, or pass it as an
227 additional parameter to LA_PRINT_STRING. -fnf */
228 get_user_print_options (&opts);
6c7a06a3 229 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
ac91cd70
PA
230 (gdb_byte *) &exp->elts[pc + 2].string, nargs,
231 NULL, 0, &opts);
79a45b7d 232 }
c906108c
SS
233 return;
234
3e43a32a
MS
235 case OP_OBJC_NSSTRING: /* Objective-C Foundation Class
236 NSString constant. */
79a45b7d
TT
237 {
238 struct value_print_options opts;
d7f9d729 239
79a45b7d
TT
240 nargs = longest_to_int (exp->elts[pc + 1].longconst);
241 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
242 fputs_filtered ("@\"", stream);
243 get_user_print_options (&opts);
6c7a06a3 244 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
ac91cd70
PA
245 (gdb_byte *) &exp->elts[pc + 2].string, nargs,
246 NULL, 0, &opts);
79a45b7d
TT
247 fputs_filtered ("\"", stream);
248 }
82eeeb94
AF
249 return;
250
251 case OP_OBJC_MSGCALL:
252 { /* Objective C message (method) call. */
82eeeb94
AF
253 (*pos) += 3;
254 nargs = longest_to_int (exp->elts[pc + 2].longconst);
255 fprintf_unfiltered (stream, "[");
256 print_subexp (exp, pos, stream, PREC_SUFFIX);
66920317
TT
257 gdb::unique_xmalloc_ptr<char> selector
258 = target_read_string (exp->elts[pc + 1].longconst, 1024);
259 if (selector == nullptr)
260 error (_("bad selector"));
82eeeb94
AF
261 if (nargs)
262 {
263 char *s, *nextS;
d7f9d729 264
e83e4e24 265 s = selector.get ();
82eeeb94
AF
266 for (tem = 0; tem < nargs; tem++)
267 {
268 nextS = strchr (s, ':');
fcd776e5 269 gdb_assert (nextS); /* Make sure we found ':'. */
82eeeb94
AF
270 *nextS = '\0';
271 fprintf_unfiltered (stream, " %s: ", s);
272 s = nextS + 1;
273 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
274 }
275 }
276 else
277 {
e83e4e24 278 fprintf_unfiltered (stream, " %s", selector.get ());
82eeeb94
AF
279 }
280 fprintf_unfiltered (stream, "]");
82eeeb94
AF
281 return;
282 }
283
c906108c
SS
284 case OP_ARRAY:
285 (*pos) += 3;
286 nargs = longest_to_int (exp->elts[pc + 2].longconst);
287 nargs -= longest_to_int (exp->elts[pc + 1].longconst);
288 nargs++;
289 tem = 0;
290 if (exp->elts[pc + 4].opcode == OP_LONG
b806fb9a
UW
291 && exp->elts[pc + 5].type
292 == builtin_type (exp->gdbarch)->builtin_char
c906108c
SS
293 && exp->language_defn->la_language == language_c)
294 {
295 /* Attempt to print C character arrays using string syntax.
296 Walk through the args, picking up one character from each
297 of the OP_LONG expression elements. If any array element
298 does not match our expection of what we should find for
299 a simple string, revert back to array printing. Note that
300 the last expression element is an explicit null terminator
0963b4bd 301 byte, which doesn't get printed. */
224c3ddb 302 tempstr = (char *) alloca (nargs);
c906108c
SS
303 pc += 4;
304 while (tem < nargs)
305 {
306 if (exp->elts[pc].opcode != OP_LONG
b806fb9a
UW
307 || exp->elts[pc + 1].type
308 != builtin_type (exp->gdbarch)->builtin_char)
c906108c 309 {
0963b4bd
MS
310 /* Not a simple array of char, use regular array
311 printing. */
c906108c
SS
312 tem = 0;
313 break;
314 }
315 else
316 {
317 tempstr[tem++] =
318 longest_to_int (exp->elts[pc + 2].longconst);
319 pc += 4;
320 }
321 }
322 }
323 if (tem > 0)
324 {
79a45b7d 325 struct value_print_options opts;
d7f9d729 326
79a45b7d 327 get_user_print_options (&opts);
6c7a06a3 328 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
ac91cd70 329 (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts);
c906108c
SS
330 (*pos) = pc;
331 }
332 else
333 {
db034ac5 334 fputs_filtered (" {", stream);
c906108c
SS
335 for (tem = 0; tem < nargs; tem++)
336 {
337 if (tem != 0)
338 {
339 fputs_filtered (", ", stream);
340 }
341 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
342 }
db034ac5 343 fputs_filtered ("}", stream);
c906108c
SS
344 }
345 return;
346
c906108c
SS
347 case TERNOP_COND:
348 if ((int) prec > (int) PREC_COMMA)
349 fputs_filtered ("(", stream);
350 /* Print the subexpressions, forcing parentheses
dda83cd7
SM
351 around any binary operations within them.
352 This is more parentheses than are strictly necessary,
353 but it looks clearer. */
c906108c
SS
354 print_subexp (exp, pos, stream, PREC_HYPER);
355 fputs_filtered (" ? ", stream);
356 print_subexp (exp, pos, stream, PREC_HYPER);
357 fputs_filtered (" : ", stream);
358 print_subexp (exp, pos, stream, PREC_HYPER);
359 if ((int) prec > (int) PREC_COMMA)
360 fputs_filtered (")", stream);
361 return;
362
363 case TERNOP_SLICE:
c906108c
SS
364 print_subexp (exp, pos, stream, PREC_SUFFIX);
365 fputs_filtered ("(", stream);
366 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
367 fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream);
368 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
369 fputs_filtered (")", stream);
370 return;
371
372 case STRUCTOP_STRUCT:
373 tem = longest_to_int (exp->elts[pc + 1].longconst);
374 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
375 print_subexp (exp, pos, stream, PREC_SUFFIX);
376 fputs_filtered (".", stream);
377 fputs_filtered (&exp->elts[pc + 2].string, stream);
378 return;
379
0963b4bd 380 /* Will not occur for Modula-2. */
c906108c
SS
381 case STRUCTOP_PTR:
382 tem = longest_to_int (exp->elts[pc + 1].longconst);
383 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
384 print_subexp (exp, pos, stream, PREC_SUFFIX);
385 fputs_filtered ("->", stream);
386 fputs_filtered (&exp->elts[pc + 2].string, stream);
387 return;
388
0534816d
DJ
389 case STRUCTOP_MEMBER:
390 print_subexp (exp, pos, stream, PREC_SUFFIX);
391 fputs_filtered (".*", stream);
392 print_subexp (exp, pos, stream, PREC_SUFFIX);
393 return;
394
395 case STRUCTOP_MPTR:
396 print_subexp (exp, pos, stream, PREC_SUFFIX);
397 fputs_filtered ("->*", stream);
398 print_subexp (exp, pos, stream, PREC_SUFFIX);
399 return;
400
c906108c
SS
401 case BINOP_SUBSCRIPT:
402 print_subexp (exp, pos, stream, PREC_SUFFIX);
403 fputs_filtered ("[", stream);
404 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
405 fputs_filtered ("]", stream);
406 return;
407
408 case UNOP_POSTINCREMENT:
409 print_subexp (exp, pos, stream, PREC_SUFFIX);
410 fputs_filtered ("++", stream);
411 return;
412
413 case UNOP_POSTDECREMENT:
414 print_subexp (exp, pos, stream, PREC_SUFFIX);
415 fputs_filtered ("--", stream);
416 return;
417
418 case UNOP_CAST:
419 (*pos) += 2;
420 if ((int) prec > (int) PREC_PREFIX)
c5aa993b 421 fputs_filtered ("(", stream);
c906108c
SS
422 fputs_filtered ("(", stream);
423 type_print (exp->elts[pc + 1].type, "", stream, 0);
424 fputs_filtered (") ", stream);
425 print_subexp (exp, pos, stream, PREC_PREFIX);
426 if ((int) prec > (int) PREC_PREFIX)
c5aa993b 427 fputs_filtered (")", stream);
c906108c
SS
428 return;
429
9eaf6705 430 case UNOP_CAST_TYPE:
9eaf6705
TT
431 if ((int) prec > (int) PREC_PREFIX)
432 fputs_filtered ("(", stream);
433 fputs_filtered ("(", stream);
434 print_subexp (exp, pos, stream, PREC_PREFIX);
435 fputs_filtered (") ", stream);
436 print_subexp (exp, pos, stream, PREC_PREFIX);
437 if ((int) prec > (int) PREC_PREFIX)
438 fputs_filtered (")", stream);
439 return;
440
4e8f195d
TT
441 case UNOP_DYNAMIC_CAST:
442 case UNOP_REINTERPRET_CAST:
443 fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast"
444 : "reinterpret_cast", stream);
445 fputs_filtered ("<", stream);
9eaf6705 446 print_subexp (exp, pos, stream, PREC_PREFIX);
4e8f195d
TT
447 fputs_filtered ("> (", stream);
448 print_subexp (exp, pos, stream, PREC_PREFIX);
449 fputs_filtered (")", stream);
450 return;
451
c906108c
SS
452 case UNOP_MEMVAL:
453 (*pos) += 2;
454 if ((int) prec > (int) PREC_PREFIX)
c5aa993b 455 fputs_filtered ("(", stream);
78134374 456 if (exp->elts[pc + 1].type->code () == TYPE_CODE_FUNC
905e0470 457 && exp->elts[pc + 3].opcode == OP_LONG)
c5aa993b 458 {
79a45b7d
TT
459 struct value_print_options opts;
460
c5aa993b
JM
461 /* We have a minimal symbol fn, probably. It's encoded
462 as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
463 Swallow the OP_LONG (including both its opcodes); ignore
464 its type; print the value in the type of the MEMVAL. */
465 (*pos) += 4;
466 val = value_at_lazy (exp->elts[pc + 1].type,
00a4c844 467 (CORE_ADDR) exp->elts[pc + 5].longconst);
2a998fc0 468 get_no_prettyformat_print_options (&opts);
79a45b7d 469 value_print (val, stream, &opts);
c5aa993b
JM
470 }
471 else
472 {
473 fputs_filtered ("{", stream);
474 type_print (exp->elts[pc + 1].type, "", stream, 0);
475 fputs_filtered ("} ", stream);
476 print_subexp (exp, pos, stream, PREC_PREFIX);
477 }
c906108c 478 if ((int) prec > (int) PREC_PREFIX)
c5aa993b 479 fputs_filtered (")", stream);
c906108c
SS
480 return;
481
9eaf6705 482 case UNOP_MEMVAL_TYPE:
9eaf6705
TT
483 if ((int) prec > (int) PREC_PREFIX)
484 fputs_filtered ("(", stream);
485 fputs_filtered ("{", stream);
486 print_subexp (exp, pos, stream, PREC_PREFIX);
487 fputs_filtered ("} ", stream);
488 print_subexp (exp, pos, stream, PREC_PREFIX);
489 if ((int) prec > (int) PREC_PREFIX)
490 fputs_filtered (")", stream);
491 return;
492
c906108c
SS
493 case BINOP_ASSIGN_MODIFY:
494 opcode = exp->elts[pc + 1].opcode;
495 (*pos) += 2;
496 myprec = PREC_ASSIGN;
497 assoc = 1;
498 assign_modify = 1;
499 op_str = "???";
500 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
501 if (op_print_tab[tem].opcode == opcode)
502 {
503 op_str = op_print_tab[tem].string;
504 break;
505 }
506 if (op_print_tab[tem].opcode != opcode)
507 /* Not found; don't try to keep going because we don't know how
508 to interpret further elements. */
8a3fe4f8 509 error (_("Invalid expression"));
c906108c
SS
510 break;
511
c5aa993b 512 /* C++ ops */
c906108c
SS
513
514 case OP_THIS:
515 ++(*pos);
5bae7c4e
AB
516 if (exp->language_defn->name_of_this () != NULL)
517 fputs_filtered (exp->language_defn->name_of_this (), stream);
aee28ec6 518 else
7f6aba03
TT
519 fprintf_styled (stream, metadata_style.style (),
520 _("<language %s has no 'this'>"),
6f7664a9 521 exp->language_defn->name ());
82eeeb94
AF
522 return;
523
c5aa993b 524 /* Modula-2 ops */
c906108c
SS
525
526 case MULTI_SUBSCRIPT:
527 (*pos) += 2;
528 nargs = longest_to_int (exp->elts[pc + 1].longconst);
529 print_subexp (exp, pos, stream, PREC_SUFFIX);
530 fprintf_unfiltered (stream, " [");
531 for (tem = 0; tem < nargs; tem++)
532 {
533 if (tem != 0)
534 fprintf_unfiltered (stream, ", ");
535 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
536 }
537 fprintf_unfiltered (stream, "]");
538 return;
539
540 case BINOP_VAL:
c5aa993b
JM
541 (*pos) += 2;
542 fprintf_unfiltered (stream, "VAL(");
543 type_print (exp->elts[pc + 1].type, "", stream, 0);
544 fprintf_unfiltered (stream, ",");
545 print_subexp (exp, pos, stream, PREC_PREFIX);
546 fprintf_unfiltered (stream, ")");
c906108c 547 return;
c5aa993b 548
600ea1be
JK
549 case TYPE_INSTANCE:
550 {
3693fdb3
PA
551 type_instance_flags flags
552 = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst);
553 LONGEST count = exp->elts[pc + 2].longconst;
600ea1be 554
3693fdb3
PA
555 /* The FLAGS. */
556 (*pos)++;
600ea1be
JK
557 /* The COUNT. */
558 (*pos)++;
3693fdb3 559 fputs_unfiltered ("TypeInstance(", stream);
600ea1be
JK
560 while (count-- > 0)
561 {
562 type_print (exp->elts[(*pos)++].type, "", stream, 0);
563 if (count > 0)
564 fputs_unfiltered (",", stream);
565 }
566 fputs_unfiltered (",", stream);
567 /* Ending COUNT and ending TYPE_INSTANCE. */
568 (*pos) += 2;
569 print_subexp (exp, pos, stream, PREC_PREFIX);
3693fdb3
PA
570
571 if (flags & TYPE_INSTANCE_FLAG_CONST)
572 fputs_unfiltered (",const", stream);
573 if (flags & TYPE_INSTANCE_FLAG_VOLATILE)
574 fputs_unfiltered (",volatile", stream);
575
600ea1be
JK
576 fputs_unfiltered (")", stream);
577 return;
578 }
579
01739a3b 580 case OP_RANGE:
e4b8a1c8 581 {
f2d8e4c5 582 enum range_flag range_flag;
e4b8a1c8 583
f2d8e4c5 584 range_flag = (enum range_flag)
e4b8a1c8
TT
585 longest_to_int (exp->elts[pc + 1].longconst);
586 *pos += 2;
587
f2d8e4c5 588 if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE)
6873858b 589 fputs_filtered ("EXCLUSIVE_", stream);
e4b8a1c8 590 fputs_filtered ("RANGE(", stream);
f2d8e4c5 591 if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
e4b8a1c8
TT
592 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
593 fputs_filtered ("..", stream);
f2d8e4c5 594 if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
e4b8a1c8
TT
595 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
596 fputs_filtered (")", stream);
597 return;
598 }
599
c5aa993b 600 /* Default ops */
c906108c
SS
601
602 default:
603 op_str = "???";
604 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
605 if (op_print_tab[tem].opcode == opcode)
606 {
607 op_str = op_print_tab[tem].string;
608 myprec = op_print_tab[tem].precedence;
609 assoc = op_print_tab[tem].right_assoc;
610 break;
611 }
612 if (op_print_tab[tem].opcode != opcode)
613 /* Not found; don't try to keep going because we don't know how
614 to interpret further elements. For example, this happens
615 if opcode is OP_TYPE. */
8a3fe4f8 616 error (_("Invalid expression"));
c5aa993b 617 }
c906108c 618
0963b4bd 619 /* Note that PREC_BUILTIN will always emit parentheses. */
c906108c
SS
620 if ((int) myprec < (int) prec)
621 fputs_filtered ("(", stream);
622 if ((int) opcode > (int) BINOP_END)
623 {
624 if (assoc)
625 {
626 /* Unary postfix operator. */
627 print_subexp (exp, pos, stream, PREC_SUFFIX);
628 fputs_filtered (op_str, stream);
629 }
630 else
631 {
632 /* Unary prefix operator. */
633 fputs_filtered (op_str, stream);
634 if (myprec == PREC_BUILTIN_FUNCTION)
635 fputs_filtered ("(", stream);
636 print_subexp (exp, pos, stream, PREC_PREFIX);
637 if (myprec == PREC_BUILTIN_FUNCTION)
638 fputs_filtered (")", stream);
639 }
640 }
641 else
642 {
643 /* Binary operator. */
644 /* Print left operand.
dda83cd7
SM
645 If operator is right-associative,
646 increment precedence for this operand. */
c906108c
SS
647 print_subexp (exp, pos, stream,
648 (enum precedence) ((int) myprec + assoc));
649 /* Print the operator itself. */
650 if (assign_modify)
651 fprintf_filtered (stream, " %s= ", op_str);
652 else if (op_str[0] == ',')
653 fprintf_filtered (stream, "%s ", op_str);
654 else
655 fprintf_filtered (stream, " %s ", op_str);
656 /* Print right operand.
dda83cd7
SM
657 If operator is left-associative,
658 increment precedence for this operand. */
c906108c
SS
659 print_subexp (exp, pos, stream,
660 (enum precedence) ((int) myprec + !assoc));
661 }
662
663 if ((int) myprec < (int) prec)
664 fputs_filtered (")", stream);
665}
666
667/* Return the operator corresponding to opcode OP as
668 a string. NULL indicates that the opcode was not found in the
669 current language table. */
a121b7c1 670const char *
fba45db2 671op_string (enum exp_opcode op)
c906108c
SS
672{
673 int tem;
f86f5ca3 674 const struct op_print *op_print_tab;
c906108c 675
b7c6e27d 676 op_print_tab = current_language->opcode_print_table ();
c906108c
SS
677 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
678 if (op_print_tab[tem].opcode == op)
679 return op_print_tab[tem].string;
680 return NULL;
681}
682
c906108c
SS
683/* Support for dumping the raw data from expressions in a human readable
684 form. */
685
24daaebc 686static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
c906108c 687
5f9769d1
PH
688/* Default name for the standard operator OPCODE (i.e., one defined in
689 the definition of enum exp_opcode). */
690
a121b7c1 691const char *
88b91969 692op_name (enum exp_opcode opcode)
c906108c
SS
693{
694 switch (opcode)
695 {
696 default:
697 {
698 static char buf[30];
699
08850b56 700 xsnprintf (buf, sizeof (buf), "<unknown %d>", opcode);
c906108c
SS
701 return buf;
702 }
56c12414
JK
703#define OP(name) \
704 case name: \
705 return #name ;
706#include "std-operator.def"
88b91969
TT
707#include "ada-operator.def"
708#include "fortran-operator.def"
56c12414 709#undef OP
c906108c
SS
710 }
711}
712
a411cd0e
DE
713/* Print a raw dump of expression EXP to STREAM.
714 NOTE, if non-NULL, is printed as extra explanatory text. */
715
c906108c 716void
24daaebc 717dump_raw_expression (struct expression *exp, struct ui_file *stream,
a121b7c1 718 const char *note)
c906108c
SS
719{
720 int elt;
c906108c
SS
721 char *eltscan;
722 int eltsize;
723
724 fprintf_filtered (stream, "Dump of expression @ ");
d4f3574e 725 gdb_print_host_address (exp, stream);
a411cd0e
DE
726 if (note)
727 fprintf_filtered (stream, ", %s:", note);
728 fprintf_filtered (stream, "\n\tLanguage %s, %d elements, %ld bytes each.\n",
6f7664a9 729 exp->language_defn->name (), exp->nelts,
9d271fd8 730 (long) sizeof (union exp_element));
c906108c
SS
731 fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode",
732 "Hex Value", "String Value");
c5aa993b 733 for (elt = 0; elt < exp->nelts; elt++)
c906108c
SS
734 {
735 fprintf_filtered (stream, "\t%5d ", elt);
c906108c 736
88b91969 737 const char *opcode_name = op_name (exp->elts[elt].opcode);
c906108c 738 fprintf_filtered (stream, "%20s ", opcode_name);
a121b7c1 739
c5aa993b 740 print_longest (stream, 'd', 0, exp->elts[elt].longconst);
c906108c
SS
741 fprintf_filtered (stream, " ");
742
743 for (eltscan = (char *) &exp->elts[elt],
c5aa993b 744 eltsize = sizeof (union exp_element);
c906108c
SS
745 eltsize-- > 0;
746 eltscan++)
747 {
748 fprintf_filtered (stream, "%c",
749 isprint (*eltscan) ? (*eltscan & 0xFF) : '.');
750 }
751 fprintf_filtered (stream, "\n");
752 }
753}
754
24daaebc
PH
755/* Dump the subexpression of prefix expression EXP whose operator is at
756 position ELT onto STREAM. Returns the position of the next
757 subexpression in EXP. */
c906108c 758
24daaebc 759int
fba45db2 760dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
c906108c
SS
761{
762 static int indent = 0;
763 int i;
764
765 fprintf_filtered (stream, "\n");
766 fprintf_filtered (stream, "\t%5d ", elt);
767
768 for (i = 1; i <= indent; i++)
769 fprintf_filtered (stream, " ");
770 indent += 2;
771
88b91969 772 fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode));
c906108c 773
24daaebc
PH
774 elt = dump_subexp_body (exp, stream, elt);
775
776 indent -= 2;
777
778 return elt;
779}
780
781/* Dump the operands of prefix expression EXP whose opcode is at
782 position ELT onto STREAM. Returns the position of the next
783 subexpression in EXP. */
784
785static int
786dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
5f9769d1 787{
5aba6ebe
AB
788 return exp->language_defn->expression_ops ()->dump_subexp_body (exp, stream,
789 elt);
5f9769d1
PH
790}
791
6d816919
AB
792/* See parser-defs.h. */
793
794int
795dump_subexp_body_funcall (struct expression *exp,
796 struct ui_file *stream, int elt)
797{
798 int nargs = longest_to_int (exp->elts[elt].longconst);
799 fprintf_filtered (stream, "Number of args: %d", nargs);
800 elt += 2;
801
802 for (int i = 1; i <= nargs + 1; i++)
803 elt = dump_subexp (exp, stream, elt);
804
805 return elt;
806}
807
5f9769d1
PH
808/* Default value for subexp_body in exp_descriptor vector. */
809
810int
811dump_subexp_body_standard (struct expression *exp,
812 struct ui_file *stream, int elt)
24daaebc
PH
813{
814 int opcode = exp->elts[elt++].opcode;
815
816 switch (opcode)
c906108c
SS
817 {
818 case TERNOP_COND:
819 case TERNOP_SLICE:
c906108c 820 elt = dump_subexp (exp, stream, elt);
cb969d61 821 /* FALL THROUGH */
c906108c
SS
822 case BINOP_ADD:
823 case BINOP_SUB:
824 case BINOP_MUL:
825 case BINOP_DIV:
826 case BINOP_REM:
827 case BINOP_MOD:
828 case BINOP_LSH:
829 case BINOP_RSH:
830 case BINOP_LOGICAL_AND:
831 case BINOP_LOGICAL_OR:
832 case BINOP_BITWISE_AND:
833 case BINOP_BITWISE_IOR:
834 case BINOP_BITWISE_XOR:
835 case BINOP_EQUAL:
836 case BINOP_NOTEQUAL:
837 case BINOP_LESS:
838 case BINOP_GTR:
839 case BINOP_LEQ:
840 case BINOP_GEQ:
841 case BINOP_REPEAT:
842 case BINOP_ASSIGN:
843 case BINOP_COMMA:
844 case BINOP_SUBSCRIPT:
845 case BINOP_EXP:
846 case BINOP_MIN:
847 case BINOP_MAX:
c906108c
SS
848 case BINOP_INTDIV:
849 case BINOP_ASSIGN_MODIFY:
850 case BINOP_VAL:
c906108c 851 case BINOP_CONCAT:
c906108c 852 case BINOP_END:
0534816d
DJ
853 case STRUCTOP_MEMBER:
854 case STRUCTOP_MPTR:
c906108c 855 elt = dump_subexp (exp, stream, elt);
cb969d61 856 /* FALL THROUGH */
c906108c
SS
857 case UNOP_NEG:
858 case UNOP_LOGICAL_NOT:
859 case UNOP_COMPLEMENT:
860 case UNOP_IND:
861 case UNOP_ADDR:
862 case UNOP_PREINCREMENT:
863 case UNOP_POSTINCREMENT:
864 case UNOP_PREDECREMENT:
865 case UNOP_POSTDECREMENT:
866 case UNOP_SIZEOF:
007e1530 867 case UNOP_ALIGNOF:
c906108c
SS
868 case UNOP_PLUS:
869 case UNOP_CAP:
870 case UNOP_CHR:
871 case UNOP_ORD:
872 case UNOP_ABS:
873 case UNOP_FLOAT:
874 case UNOP_HIGH:
875 case UNOP_MAX:
876 case UNOP_MIN:
877 case UNOP_ODD:
878 case UNOP_TRUNC:
c906108c
SS
879 elt = dump_subexp (exp, stream, elt);
880 break;
881 case OP_LONG:
d4f3574e
SS
882 fprintf_filtered (stream, "Type @");
883 gdb_print_host_address (exp->elts[elt].type, stream);
884 fprintf_filtered (stream, " (");
c906108c
SS
885 type_print (exp->elts[elt].type, NULL, stream, 0);
886 fprintf_filtered (stream, "), value %ld (0x%lx)",
c5aa993b
JM
887 (long) exp->elts[elt + 1].longconst,
888 (long) exp->elts[elt + 1].longconst);
c906108c
SS
889 elt += 3;
890 break;
edd079d9 891 case OP_FLOAT:
d4f3574e
SS
892 fprintf_filtered (stream, "Type @");
893 gdb_print_host_address (exp->elts[elt].type, stream);
894 fprintf_filtered (stream, " (");
c906108c 895 type_print (exp->elts[elt].type, NULL, stream, 0);
edd079d9
UW
896 fprintf_filtered (stream, "), value ");
897 print_floating (exp->elts[elt + 1].floatconst,
898 exp->elts[elt].type, stream);
c906108c
SS
899 elt += 3;
900 break;
901 case OP_VAR_VALUE:
d4f3574e
SS
902 fprintf_filtered (stream, "Block @");
903 gdb_print_host_address (exp->elts[elt].block, stream);
904 fprintf_filtered (stream, ", symbol @");
905 gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
906 fprintf_filtered (stream, " (%s)",
987012b8 907 exp->elts[elt + 1].symbol->print_name ());
c906108c
SS
908 elt += 3;
909 break;
74ea4be4
PA
910 case OP_VAR_MSYM_VALUE:
911 fprintf_filtered (stream, "Objfile @");
912 gdb_print_host_address (exp->elts[elt].objfile, stream);
913 fprintf_filtered (stream, ", msymbol @");
914 gdb_print_host_address (exp->elts[elt + 1].msymbol, stream);
915 fprintf_filtered (stream, " (%s)",
c9d95fa3 916 exp->elts[elt + 1].msymbol->print_name ());
74ea4be4
PA
917 elt += 3;
918 break;
36b11add
JK
919 case OP_VAR_ENTRY_VALUE:
920 fprintf_filtered (stream, "Entry value of symbol @");
921 gdb_print_host_address (exp->elts[elt].symbol, stream);
922 fprintf_filtered (stream, " (%s)",
987012b8 923 exp->elts[elt].symbol->print_name ());
36b11add
JK
924 elt += 2;
925 break;
c906108c
SS
926 case OP_LAST:
927 fprintf_filtered (stream, "History element %ld",
c5aa993b 928 (long) exp->elts[elt].longconst);
c906108c
SS
929 elt += 2;
930 break;
931 case OP_REGISTER:
67f3407f
DJ
932 fprintf_filtered (stream, "Register $%s", &exp->elts[elt + 1].string);
933 elt += 3 + BYTES_TO_EXP_ELEM (exp->elts[elt].longconst + 1);
c906108c
SS
934 break;
935 case OP_INTERNALVAR:
d4f3574e
SS
936 fprintf_filtered (stream, "Internal var @");
937 gdb_print_host_address (exp->elts[elt].internalvar, stream);
938 fprintf_filtered (stream, " (%s)",
4fa62494 939 internalvar_name (exp->elts[elt].internalvar));
c906108c
SS
940 elt += 2;
941 break;
942 case OP_FUNCALL:
6d816919 943 elt = dump_subexp_body_funcall (exp, stream, elt);
c906108c
SS
944 break;
945 case OP_ARRAY:
946 {
947 int lower, upper;
948 int i;
949
950 lower = longest_to_int (exp->elts[elt].longconst);
951 upper = longest_to_int (exp->elts[elt + 1].longconst);
952
953 fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper);
954 elt += 3;
955
956 for (i = 1; i <= upper - lower + 1; i++)
957 elt = dump_subexp (exp, stream, elt);
958 }
959 break;
4e8f195d
TT
960 case UNOP_DYNAMIC_CAST:
961 case UNOP_REINTERPRET_CAST:
9eaf6705
TT
962 case UNOP_CAST_TYPE:
963 case UNOP_MEMVAL_TYPE:
9eaf6705
TT
964 fprintf_filtered (stream, " (");
965 elt = dump_subexp (exp, stream, elt);
966 fprintf_filtered (stream, ")");
967 elt = dump_subexp (exp, stream, elt);
968 break;
969 case UNOP_MEMVAL:
970 case UNOP_CAST:
d4f3574e
SS
971 fprintf_filtered (stream, "Type @");
972 gdb_print_host_address (exp->elts[elt].type, stream);
973 fprintf_filtered (stream, " (");
c906108c
SS
974 type_print (exp->elts[elt].type, NULL, stream, 0);
975 fprintf_filtered (stream, ")");
976 elt = dump_subexp (exp, stream, elt + 2);
977 break;
978 case OP_TYPE:
d4f3574e
SS
979 fprintf_filtered (stream, "Type @");
980 gdb_print_host_address (exp->elts[elt].type, stream);
981 fprintf_filtered (stream, " (");
c906108c
SS
982 type_print (exp->elts[elt].type, NULL, stream, 0);
983 fprintf_filtered (stream, ")");
984 elt += 2;
985 break;
608b4967
TT
986 case OP_TYPEOF:
987 case OP_DECLTYPE:
988 fprintf_filtered (stream, "Typeof (");
989 elt = dump_subexp (exp, stream, elt);
990 fprintf_filtered (stream, ")");
991 break;
6e72ca20
TT
992 case OP_TYPEID:
993 fprintf_filtered (stream, "typeid (");
994 elt = dump_subexp (exp, stream, elt);
995 fprintf_filtered (stream, ")");
996 break;
c906108c
SS
997 case STRUCTOP_STRUCT:
998 case STRUCTOP_PTR:
999 {
1000 char *elem_name;
1001 int len;
1002
1003 len = longest_to_int (exp->elts[elt].longconst);
1004 elem_name = &exp->elts[elt + 1].string;
1005
1006 fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name);
1007 elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1));
1008 }
1009 break;
1010 case OP_SCOPE:
1011 {
1012 char *elem_name;
1013 int len;
1014
d4f3574e
SS
1015 fprintf_filtered (stream, "Type @");
1016 gdb_print_host_address (exp->elts[elt].type, stream);
1017 fprintf_filtered (stream, " (");
c906108c
SS
1018 type_print (exp->elts[elt].type, NULL, stream, 0);
1019 fprintf_filtered (stream, ") ");
1020
1021 len = longest_to_int (exp->elts[elt + 1].longconst);
1022 elem_name = &exp->elts[elt + 2].string;
1023
1024 fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
1025 elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
1026 }
1027 break;
858be34c
PA
1028
1029 case OP_FUNC_STATIC_VAR:
1030 {
1031 int len = longest_to_int (exp->elts[elt].longconst);
1032 const char *var_name = &exp->elts[elt + 1].string;
1033 fprintf_filtered (stream, "Field name: `%.*s'", len, var_name);
1034 elt += 3 + BYTES_TO_EXP_ELEM (len + 1);
1035 }
1036 break;
1037
600ea1be
JK
1038 case TYPE_INSTANCE:
1039 {
3693fdb3
PA
1040 type_instance_flags flags
1041 = (type_instance_flag_value) longest_to_int (exp->elts[elt++].longconst);
1042 LONGEST len = exp->elts[elt++].longconst;
600ea1be
JK
1043 fprintf_filtered (stream, "%s TypeInstance: ", plongest (len));
1044 while (len-- > 0)
1045 {
1046 fprintf_filtered (stream, "Type @");
1047 gdb_print_host_address (exp->elts[elt].type, stream);
1048 fprintf_filtered (stream, " (");
1049 type_print (exp->elts[elt].type, NULL, stream, 0);
1050 fprintf_filtered (stream, ")");
1051 elt++;
1052 if (len > 0)
1053 fputs_filtered (", ", stream);
1054 }
3693fdb3
PA
1055
1056 fprintf_filtered (stream, " Flags: %s (", hex_string (flags));
1057 bool space = false;
1058 auto print_one = [&] (const char *mod)
1059 {
1060 if (space)
1061 fputs_filtered (" ", stream);
1062 space = true;
d6b687ac 1063 fprintf_filtered (stream, "%s", mod);
3693fdb3
PA
1064 };
1065 if (flags & TYPE_INSTANCE_FLAG_CONST)
1066 print_one ("const");
1067 if (flags & TYPE_INSTANCE_FLAG_VOLATILE)
1068 print_one ("volatile");
1069 fprintf_filtered (stream, ")");
1070
600ea1be
JK
1071 /* Ending LEN and ending TYPE_INSTANCE. */
1072 elt += 2;
1073 elt = dump_subexp (exp, stream, elt);
1074 }
1075 break;
2d40be18
SM
1076 case OP_STRING:
1077 {
1078 LONGEST len = exp->elts[elt].longconst;
1079 LONGEST type = exp->elts[elt + 1].longconst;
1080
1081 fprintf_filtered (stream, "Language-specific string type: %s",
1082 plongest (type));
1083
1084 /* Skip length. */
1085 elt += 1;
1086
1087 /* Skip string content. */
1088 elt += BYTES_TO_EXP_ELEM (len);
1089
1090 /* Skip length and ending OP_STRING. */
1091 elt += 2;
1092 }
1093 break;
01739a3b 1094 case OP_RANGE:
e4b8a1c8 1095 {
f2d8e4c5 1096 enum range_flag range_flag;
e4b8a1c8 1097
f2d8e4c5 1098 range_flag = (enum range_flag)
e4b8a1c8
TT
1099 longest_to_int (exp->elts[elt].longconst);
1100 elt += 2;
1101
f2d8e4c5 1102 if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE)
2f1b18db
AB
1103 fputs_filtered ("Exclusive", stream);
1104 fputs_filtered ("Range '", stream);
f2d8e4c5 1105 if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
2f1b18db
AB
1106 fputs_filtered ("EXP", stream);
1107 fputs_filtered ("..", stream);
f2d8e4c5 1108 if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
2f1b18db 1109 fputs_filtered ("EXP", stream);
6b4c676c
AB
1110 if (range_flag & RANGE_HAS_STRIDE)
1111 fputs_filtered (":EXP", stream);
2f1b18db 1112 fputs_filtered ("'", stream);
e4b8a1c8 1113
f2d8e4c5 1114 if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
e4b8a1c8 1115 elt = dump_subexp (exp, stream, elt);
f2d8e4c5 1116 if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
e4b8a1c8 1117 elt = dump_subexp (exp, stream, elt);
6b4c676c
AB
1118 if (range_flag & RANGE_HAS_STRIDE)
1119 elt = dump_subexp (exp, stream, elt);
e4b8a1c8
TT
1120 }
1121 break;
1122
c906108c
SS
1123 default:
1124 case OP_NULL:
c906108c 1125 case MULTI_SUBSCRIPT:
c906108c 1126 case OP_COMPLEX:
c906108c
SS
1127 case OP_BOOL:
1128 case OP_M2_STRING:
1129 case OP_THIS:
c906108c 1130 case OP_NAME:
c906108c
SS
1131 fprintf_filtered (stream, "Unknown format");
1132 }
1133
c906108c
SS
1134 return elt;
1135}
1136
1137void
24daaebc 1138dump_prefix_expression (struct expression *exp, struct ui_file *stream)
c906108c
SS
1139{
1140 int elt;
1141
1142 fprintf_filtered (stream, "Dump of expression @ ");
d4f3574e 1143 gdb_print_host_address (exp, stream);
24daaebc 1144 fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
4f485ebc 1145 print_expression (exp, stream);
9d271fd8 1146 fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
6f7664a9 1147 exp->language_defn->name (), exp->nelts,
9d271fd8 1148 (long) sizeof (union exp_element));
c906108c
SS
1149 fputs_filtered ("\n", stream);
1150
c5aa993b 1151 for (elt = 0; elt < exp->nelts;)
c906108c
SS
1152 elt = dump_subexp (exp, stream, elt);
1153 fputs_filtered ("\n", stream);
1154}
This page took 1.521655 seconds and 4 git commands to generate.