|
|
1.1 ! root 1: /* Print in infix form a struct expression. ! 2: Copyright (C) 1986 Free Software Foundation, Inc. ! 3: ! 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. ! 9: ! 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. ! 16: ! 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! ! 19: */ ! 20: ! 21: #include "defs.h" ! 22: #include "symtab.h" ! 23: #include "expression.h" ! 24: ! 25: #include <stdio.h> ! 26: ! 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. */ ! 34: enum precedence ! 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 }; ! 39: ! 40: /* Table mapping opcodes into strings for printing operators ! 41: and precedences of the operators. */ ! 42: ! 43: struct op_print ! 44: { ! 45: char *string; ! 46: enum exp_opcode opcode; ! 47: /* Precedence of operator. These values are used only by comparisons. */ ! 48: enum precedence precedence; ! 49: int right_assoc; ! 50: }; ! 51: ! 52: static struct op_print op_print_tab[] = ! 53: { ! 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} ! 83: }; ! 84: ! 85: static void print_subexp (); ! 86: ! 87: void ! 88: print_expression (exp, stream) ! 89: struct expression *exp; ! 90: FILE *stream; ! 91: { ! 92: int pc = 0; ! 93: print_subexp (exp, &pc, stream, PREC_NULL); ! 94: } ! 95: ! 96: /* Print the subexpression of EXP that starts in position POS, on STREAM. ! 97: PREC is the precedence of the surrounding operator; ! 98: if the precedence of the main operator of this subexpression is less, ! 99: parentheses are needed here. */ ! 100: ! 101: static void ! 102: print_subexp (exp, pos, stream, prec) ! 103: register struct expression *exp; ! 104: register int *pos; ! 105: FILE *stream; ! 106: enum precedence prec; ! 107: { ! 108: register int tem; ! 109: register int pc; ! 110: int nargs; ! 111: register char *op_str; ! 112: int assign_modify = 0; ! 113: enum exp_opcode opcode; ! 114: enum precedence myprec; ! 115: /* Set to 1 for a right-associative operator. */ ! 116: int assoc; ! 117: ! 118: pc = (*pos)++; ! 119: opcode = exp->elts[pc].opcode; ! 120: switch (opcode) ! 121: { ! 122: case OP_LONG: ! 123: (*pos) += 3; ! 124: value_print (value_from_long (exp->elts[pc + 1].type, ! 125: exp->elts[pc + 2].longconst), ! 126: stream, 0); ! 127: return; ! 128: ! 129: case OP_DOUBLE: ! 130: (*pos) += 3; ! 131: value_print (value_from_double (exp->elts[pc + 1].type, ! 132: exp->elts[pc + 2].doubleconst), ! 133: stream, 0); ! 134: return; ! 135: ! 136: case OP_VAR_VALUE: ! 137: (*pos) += 2; ! 138: fprintf (stream, "%s", SYMBOL_NAME (exp->elts[pc + 1].symbol)); ! 139: return; ! 140: ! 141: case OP_LAST: ! 142: (*pos) += 2; ! 143: fprintf (stream, "$%d", exp->elts[pc + 1].longconst); ! 144: return; ! 145: ! 146: case OP_REGISTER: ! 147: (*pos) += 2; ! 148: fprintf (stream, "$%s", reg_names[exp->elts[pc + 1].longconst]); ! 149: return; ! 150: ! 151: case OP_INTERNALVAR: ! 152: (*pos) += 2; ! 153: fprintf (stream, "$%s", ! 154: internalvar_name (exp->elts[pc + 1].internalvar)); ! 155: return; ! 156: ! 157: case OP_FUNCALL: ! 158: (*pos) += 2; ! 159: nargs = exp->elts[pc + 1].longconst; ! 160: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 161: fprintf (stream, " ("); ! 162: for (tem = 0; tem < nargs; tem++) ! 163: { ! 164: if (tem > 0) ! 165: fprintf (stream, ", "); ! 166: print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); ! 167: } ! 168: fprintf (stream, ")"); ! 169: return; ! 170: ! 171: case OP_STRING: ! 172: nargs = strlen (&exp->elts[pc + 1].string); ! 173: (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element); ! 174: fprintf (stream, "\""); ! 175: for (tem = 0; tem < nargs; tem++) ! 176: printchar ((&exp->elts[pc + 1].string)[tem], stream, '"'); ! 177: fprintf (stream, "\""); ! 178: return; ! 179: ! 180: case TERNOP_COND: ! 181: if ((int) prec > (int) PREC_COMMA) ! 182: fprintf (stream, "("); ! 183: /* Print the subexpressions, forcing parentheses ! 184: around any binary operations within them. ! 185: This is more parentheses than are strictly necessary, ! 186: but it looks clearer. */ ! 187: print_subexp (exp, pos, stream, PREC_HYPER); ! 188: fprintf (stream, " ? "); ! 189: print_subexp (exp, pos, stream, PREC_HYPER); ! 190: fprintf (stream, " : "); ! 191: print_subexp (exp, pos, stream, PREC_HYPER); ! 192: if ((int) prec > (int) PREC_COMMA) ! 193: fprintf (stream, ")"); ! 194: return; ! 195: ! 196: case STRUCTOP_STRUCT: ! 197: tem = strlen (&exp->elts[pc + 1].string); ! 198: (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); ! 199: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 200: fprintf (stream, ".%s", &exp->elts[pc + 1].string); ! 201: return; ! 202: ! 203: case STRUCTOP_PTR: ! 204: tem = strlen (&exp->elts[pc + 1].string); ! 205: (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); ! 206: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 207: fprintf (stream, "->%s", &exp->elts[pc + 1].string); ! 208: return; ! 209: ! 210: case BINOP_SUBSCRIPT: ! 211: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 212: fprintf (stream, "["); ! 213: print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); ! 214: fprintf (stream, "]"); ! 215: return; ! 216: ! 217: case UNOP_POSTINCREMENT: ! 218: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 219: fprintf (stream, "++"); ! 220: return; ! 221: ! 222: case UNOP_POSTDECREMENT: ! 223: print_subexp (exp, pos, stream, PREC_SUFFIX); ! 224: fprintf (stream, "--"); ! 225: return; ! 226: ! 227: case UNOP_CAST: ! 228: (*pos) += 2; ! 229: if ((int) prec > (int) PREC_PREFIX) ! 230: fprintf (stream, "("); ! 231: fprintf (stream, "("); ! 232: type_print (exp->elts[pc + 1].type, "", stream, 0); ! 233: fprintf (stream, ") "); ! 234: print_subexp (exp, pos, stream, PREC_PREFIX); ! 235: if ((int) prec > (int) PREC_PREFIX) ! 236: fprintf (stream, ")"); ! 237: return; ! 238: ! 239: case UNOP_MEMVAL: ! 240: (*pos) += 2; ! 241: if ((int) prec > (int) PREC_PREFIX) ! 242: fprintf (stream, "("); ! 243: fprintf (stream, "{"); ! 244: type_print (exp->elts[pc + 1].type, "", stream, 0); ! 245: fprintf (stream, "} "); ! 246: print_subexp (exp, pos, stream, PREC_PREFIX); ! 247: if ((int) prec > (int) PREC_PREFIX) ! 248: fprintf (stream, ")"); ! 249: return; ! 250: ! 251: case BINOP_ASSIGN_MODIFY: ! 252: opcode = exp->elts[pc + 1].opcode; ! 253: (*pos) += 2; ! 254: myprec = PREC_ASSIGN; ! 255: assoc = 1; ! 256: assign_modify = 1; ! 257: for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++) ! 258: if (op_print_tab[tem].opcode == opcode) ! 259: { ! 260: op_str = op_print_tab[tem].string; ! 261: break; ! 262: } ! 263: ! 264: default: ! 265: for (tem = 0; tem < sizeof op_print_tab / sizeof op_print_tab[0]; tem++) ! 266: if (op_print_tab[tem].opcode == opcode) ! 267: { ! 268: op_str = op_print_tab[tem].string; ! 269: myprec = op_print_tab[tem].precedence; ! 270: assoc = op_print_tab[tem].right_assoc; ! 271: break; ! 272: } ! 273: } ! 274: ! 275: if ((int) myprec < (int) prec) ! 276: fprintf (stream, "("); ! 277: if ((int) opcode > (int) BINOP_END) ! 278: { ! 279: /* Unary prefix operator. */ ! 280: fprintf (stream, "%s", op_str); ! 281: print_subexp (exp, pos, stream, PREC_PREFIX); ! 282: } ! 283: else ! 284: { ! 285: /* Binary operator. */ ! 286: /* Print left operand. ! 287: If operator is right-associative, ! 288: increment precedence for this operand. */ ! 289: print_subexp (exp, pos, stream, (int) myprec + assoc); ! 290: /* Print the operator itself. */ ! 291: if (assign_modify) ! 292: fprintf (stream, " %s= ", op_str); ! 293: else if (op_str[0] == ',') ! 294: fprintf (stream, "%s ", op_str); ! 295: else ! 296: fprintf (stream, " %s ", op_str); ! 297: /* Print right operand. ! 298: If operator is left-associative, ! 299: increment precedence for this operand. */ ! 300: print_subexp (exp, pos, stream, (int) myprec + !assoc); ! 301: } ! 302: if ((int) myprec < (int) prec) ! 303: fprintf (stream, ")"); ! 304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.