|
|
1.1 root 1: /* Perform arithmetic and other operations on values, for GDB.
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 "initialize.h"
23: #include "param.h"
24: #include "symtab.h"
25: #include "value.h"
26: #include "expression.h"
27:
28: START_FILE
29:
30: value
31: value_add (arg1, arg2)
32: value arg1, arg2;
33: {
34: register value val, valint, valptr;
35: register int len;
36:
37: COERCE_ARRAY (arg1);
38: COERCE_ARRAY (arg2);
39:
40: if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
41: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)
42: &&
43: (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT
44: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))
45: /* Exactly one argument is a pointer, and one is an integer. */
46: {
47: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
48: {
49: valptr = arg1;
50: valint = arg2;
51: }
52: else
53: {
54: valptr = arg2;
55: valint = arg1;
56: }
57: len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));
58: if (len == 0) len = 1; /* For (void *) */
59: val = value_from_long (builtin_type_long,
60: value_as_long (valptr)
61: + (len * value_as_long (valint)));
62: VALUE_TYPE (val) = VALUE_TYPE (valptr);
63: return val;
64: }
65:
1.1.1.4 ! root 66: return value_binop (arg1, arg2, BINOP_ADD);
1.1 root 67: }
68:
69: value
70: value_sub (arg1, arg2)
71: value arg1, arg2;
72: {
73: register value val;
74:
75: COERCE_ARRAY (arg1);
76: COERCE_ARRAY (arg2);
77:
78: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
79: &&
80: TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)
81: {
82: val = value_from_long (builtin_type_long,
83: value_as_long (arg1)
84: - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) * value_as_long (arg2));
85: VALUE_TYPE (val) = VALUE_TYPE (arg1);
86: return val;
87: }
88:
89: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
90: &&
91: VALUE_TYPE (arg1) == VALUE_TYPE (arg2))
92: {
93: val = value_from_long (builtin_type_long,
94: (value_as_long (arg1) - value_as_long (arg2))
95: / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));
96: return val;
97: }
98:
1.1.1.4 ! root 99: return value_binop (arg1, arg2, BINOP_SUB);
1.1 root 100: }
101:
102: /* Return the value of ARRAY[IDX]. */
103:
104: value
105: value_subscript (array, idx)
106: value array, idx;
107: {
108: return value_ind (value_add (array, idx));
109: }
1.1.1.3 root 110:
1.1.1.4 ! root 111: /* Check to see if either argument is a structure. This is called so
! 112: we know whether to go ahead with the normal binop or look for a
! 113: user defined function instead */
! 114:
! 115: int
! 116: binop_must_be_user_defined (arg1, arg2)
! 117: value arg1, arg2;
! 118: {
! 119: return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
! 120: || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT
! 121: || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
! 122: && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)
! 123: || (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF
! 124: && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT));
! 125: }
! 126:
! 127: /* Check to see if argument is a structure. This is called so
! 128: we know whether to go ahead with the normal unop or look for a
! 129: user defined function instead */
! 130:
! 131: int unop_must_be_user_defined (arg1)
! 132: value arg1;
! 133: {
! 134: return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
! 135: || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
! 136: && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT));
! 137: }
! 138:
! 139: /* We know either arg1 or arg2 is a structure, so try to find the right
! 140: user defined function. Create an argument vector that calls
! 141: arg1.operator @ (arg1,arg2) and return that value (where '@' is any
! 142: binary operator which is legal for GNU C++). */
1.1.1.3 root 143:
144: value
1.1.1.4 ! root 145: value_x_binop (arg1, arg2, op, otherop)
1.1.1.3 root 146: value arg1, arg2;
1.1.1.4 ! root 147: int op, otherop;
1.1.1.3 root 148: {
149: value * argvec;
150: char *ptr;
151: char tstr[13];
152:
153: COERCE_ENUM (arg1);
154: COERCE_ENUM (arg2);
155:
1.1.1.4 ! root 156: /* now we know that what we have to do is construct our
! 157: arg vector and find the right function to call it with. */
1.1.1.3 root 158:
1.1.1.4 ! root 159: if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
! 160: error ("friend functions not implemented yet");
1.1 root 161:
1.1.1.4 ! root 162: argvec = (value *) alloca (sizeof (value) * 4);
! 163: argvec[1] = value_addr (arg1);
! 164: argvec[2] = arg2;
! 165: argvec[3] = 0;
! 166:
! 167: /* make the right function name up */
! 168: strcpy(tstr, "operator __");
! 169: ptr = tstr+9;
! 170: switch (op)
! 171: {
! 172: case BINOP_ADD: strcpy(ptr,"+"); break;
! 173: case BINOP_SUB: strcpy(ptr,"-"); break;
! 174: case BINOP_MUL: strcpy(ptr,"*"); break;
! 175: case BINOP_DIV: strcpy(ptr,"/"); break;
! 176: case BINOP_REM: strcpy(ptr,"%"); break;
! 177: case BINOP_LSH: strcpy(ptr,"<<"); break;
! 178: case BINOP_RSH: strcpy(ptr,">>"); break;
! 179: case BINOP_LOGAND: strcpy(ptr,"&"); break;
! 180: case BINOP_LOGIOR: strcpy(ptr,"|"); break;
! 181: case BINOP_LOGXOR: strcpy(ptr,"^"); break;
! 182: case BINOP_AND: strcpy(ptr,"&&"); break;
! 183: case BINOP_OR: strcpy(ptr,"||"); break;
! 184: case BINOP_MIN: strcpy(ptr,"<?"); break;
! 185: case BINOP_MAX: strcpy(ptr,">?"); break;
! 186: case BINOP_ASSIGN: strcpy(ptr,"="); break;
! 187: case BINOP_ASSIGN_MODIFY:
! 188: switch (otherop)
1.1.1.3 root 189: {
1.1.1.4 ! root 190: case BINOP_ADD: strcpy(ptr,"+="); break;
! 191: case BINOP_SUB: strcpy(ptr,"-="); break;
! 192: case BINOP_MUL: strcpy(ptr,"*="); break;
! 193: case BINOP_DIV: strcpy(ptr,"/="); break;
! 194: case BINOP_REM: strcpy(ptr,"%="); break;
! 195: case BINOP_LOGAND: strcpy(ptr,"&="); break;
! 196: case BINOP_LOGIOR: strcpy(ptr,"|="); break;
! 197: case BINOP_LOGXOR: strcpy(ptr,"^="); break;
1.1.1.3 root 198: default:
199: error ("Invalid binary operation specified.");
200: }
1.1.1.4 ! root 201: break;
! 202: case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break;
! 203: case BINOP_EQUAL: strcpy(ptr,"=="); break;
! 204: case BINOP_NOTEQUAL: strcpy(ptr,"!="); break;
! 205: case BINOP_LESS: strcpy(ptr,"<"); break;
! 206: case BINOP_GTR: strcpy(ptr,">"); break;
! 207: case BINOP_GEQ: strcpy(ptr,">="); break;
! 208: case BINOP_LEQ: strcpy(ptr,"<="); break;
! 209: default:
! 210: error ("Invalid binary operation specified.");
1.1.1.3 root 211: }
1.1.1.4 ! root 212: argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
! 213: if (argvec[0])
! 214: return call_function (argvec[0], 2, argvec + 1);
! 215: else error ("member function %s not found", tstr);
! 216: }
! 217:
! 218: /* We know that arg1 is a structure, so try to find a unary user
! 219: defined operator that matches the operator in question.
! 220: Create an argument vector that calls arg1.operator @ (arg1)
! 221: and return that value (where '@' is (almost) any unary operator which
! 222: is legal for GNU C++). */
! 223:
! 224: value
! 225: value_x_unop (arg1, op)
! 226: value arg1;
! 227: int op;
! 228: {
! 229: value * argvec;
! 230: char *ptr;
! 231: char tstr[13];
! 232:
! 233: COERCE_ENUM (arg1);
1.1.1.3 root 234:
1.1.1.4 ! root 235: /* now we know that what we have to do is construct our
! 236: arg vector and find the right function to call it with. */
! 237:
! 238: if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
! 239: error ("friend functions not implemented yet");
! 240:
! 241: argvec = (value *) alloca (sizeof (value) * 3);
! 242: argvec[1] = value_addr (arg1);
! 243: argvec[2] = 0;
! 244:
! 245: /* make the right function name up */
! 246: strcpy(tstr,"operator __");
! 247: ptr = tstr+9;
! 248: switch (op)
! 249: {
! 250: case UNOP_PREINCREMENT: strcpy(ptr,"++"); break;
! 251: case UNOP_PREDECREMENT: strcpy(ptr,"++"); break;
! 252: case UNOP_POSTINCREMENT: strcpy(ptr,"++"); break;
! 253: case UNOP_POSTDECREMENT: strcpy(ptr,"++"); break;
! 254: case UNOP_ZEROP: strcpy(ptr,"!"); break;
! 255: case UNOP_LOGNOT: strcpy(ptr,"~"); break;
! 256: case UNOP_NEG: strcpy(ptr,"-"); break;
! 257: default:
! 258: error ("Invalid binary operation specified.");
! 259: }
! 260: argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
! 261: if (argvec[0])
! 262: return call_function (argvec[0], 1, argvec + 1);
! 263: else error ("member function %s not found", tstr);
1.1.1.3 root 264: }
265:
1.1 root 266: /* Perform a binary operation on two integers or two floats.
267: Does not support addition and subtraction on pointers;
268: use value_add or value_sub if you want to handle those possibilities. */
269:
270: value
271: value_binop (arg1, arg2, op)
272: value arg1, arg2;
273: int op;
274: {
275: register value val;
276:
1.1.1.2 root 277: COERCE_ENUM (arg1);
278: COERCE_ENUM (arg2);
279:
1.1 root 280: if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
281: &&
282: TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
283: ||
284: (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
285: &&
286: TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
287: error ("Argument to arithmetic operation not a number.");
288:
289: if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
290: ||
291: TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
292: {
293: double v1, v2, v;
294: v1 = value_as_double (arg1);
295: v2 = value_as_double (arg2);
296: switch (op)
297: {
298: case BINOP_ADD:
299: v = v1 + v2;
300: break;
301:
302: case BINOP_SUB:
303: v = v1 - v2;
304: break;
305:
306: case BINOP_MUL:
307: v = v1 * v2;
308: break;
309:
310: case BINOP_DIV:
311: v = v1 / v2;
312: break;
313:
314: default:
315: error ("Integer-only operation on floating point number.");
316: }
317:
318: val = allocate_value (builtin_type_double);
319: *(double *) VALUE_CONTENTS (val) = v;
320: }
321: else
322: {
323: long v1, v2, v;
324: v1 = value_as_long (arg1);
325: v2 = value_as_long (arg2);
326:
327: switch (op)
328: {
329: case BINOP_ADD:
330: v = v1 + v2;
331: break;
332:
333: case BINOP_SUB:
334: v = v1 - v2;
335: break;
336:
337: case BINOP_MUL:
338: v = v1 * v2;
339: break;
340:
341: case BINOP_DIV:
342: v = v1 / v2;
343: break;
344:
345: case BINOP_REM:
346: v = v1 % v2;
347: break;
348:
349: case BINOP_LSH:
350: v = v1 << v2;
351: break;
352:
353: case BINOP_RSH:
354: v = v1 >> v2;
355: break;
356:
357: case BINOP_LOGAND:
358: v = v1 & v2;
359: break;
360:
361: case BINOP_LOGIOR:
362: v = v1 | v2;
363: break;
364:
365: case BINOP_LOGXOR:
366: v = v1 ^ v2;
367: break;
368:
369: case BINOP_AND:
370: v = v1 && v2;
371: break;
372:
373: case BINOP_OR:
374: v = v1 || v2;
375: break;
376:
1.1.1.3 root 377: case BINOP_MIN:
378: v = v1 < v2 ? v1 : v2;
379: break;
380:
381: case BINOP_MAX:
382: v = v1 > v2 ? v1 : v2;
383: break;
384:
1.1 root 385: default:
386: error ("Invalid binary operation on numbers.");
387: }
388:
389: val = allocate_value (builtin_type_long);
390: *(long *) VALUE_CONTENTS (val) = v;
391: }
392:
393: return val;
394: }
395:
396: /* Simulate the C operator ! -- return 1 if ARG1 contains zeros. */
397:
398: int
399: value_zerop (arg1)
400: value arg1;
401: {
402: register int len;
403: register char *p;
404:
405: COERCE_ARRAY (arg1);
406:
407: len = TYPE_LENGTH (VALUE_TYPE (arg1));
408: p = VALUE_CONTENTS (arg1);
409:
410: while (--len >= 0)
411: {
412: if (*p++)
413: break;
414: }
415:
416: return len < 0;
417: }
418:
419: /* Simulate the C operator == by returning a 1
420: iff ARG1 and ARG2 have equal contents. */
421:
422: int
423: value_equal (arg1, arg2)
424: register value arg1, arg2;
425:
426: {
427: register int len;
428: register char *p1, *p2;
429: enum type_code code1;
430: enum type_code code2;
431:
432: COERCE_ARRAY (arg1);
433: COERCE_ARRAY (arg2);
434:
435: code1 = TYPE_CODE (VALUE_TYPE (arg1));
436: code2 = TYPE_CODE (VALUE_TYPE (arg2));
437:
438: if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
439: return value_as_long (arg1) == value_as_long (arg2);
440: else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
441: && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
442: return value_as_double (arg1) == value_as_double (arg2);
443: else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
444: || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
445: return value_as_long (arg1) == value_as_long (arg2);
446: else if (code1 == code2
447: && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
448: == TYPE_LENGTH (VALUE_TYPE (arg2))))
449: {
450: p1 = VALUE_CONTENTS (arg1);
451: p2 = VALUE_CONTENTS (arg2);
452: while (--len >= 0)
453: {
454: if (*p1++ != *p2++)
455: break;
456: }
457: return len < 0;
458: }
459: else
460: error ("Invalid type combination in equality test.");
461: }
462:
463: /* Simulate the C operator < by returning 1
464: iff ARG1's contents are less than ARG2's. */
465:
466: int
467: value_less (arg1, arg2)
468: register value arg1, arg2;
469: {
470: register enum type_code code1;
471: register enum type_code code2;
472:
473: COERCE_ARRAY (arg1);
474: COERCE_ARRAY (arg2);
475:
476: code1 = TYPE_CODE (VALUE_TYPE (arg1));
477: code2 = TYPE_CODE (VALUE_TYPE (arg2));
478:
479: if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
480: return value_as_long (arg1) < value_as_long (arg2);
481: else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
482: && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
483: return value_as_double (arg1) < value_as_double (arg2);
484: else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
485: && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
486: return value_as_long (arg1) < value_as_long (arg2);
487: else
488: error ("Invalid type combination in ordering comparison.");
489: }
490:
491: /* The unary operators - and ~. Both free the argument ARG1. */
492:
493: value
494: value_neg (arg1)
495: register value arg1;
496: {
1.1.1.2 root 497: register struct type *type;
498:
499: COERCE_ENUM (arg1);
500:
501: type = VALUE_TYPE (arg1);
1.1 root 502:
503: if (TYPE_CODE (type) == TYPE_CODE_FLT)
504: return value_from_double (type, - value_as_double (arg1));
505: else if (TYPE_CODE (type) == TYPE_CODE_INT)
506: return value_from_long (type, - value_as_long (arg1));
507: else
508: error ("Argument to negate operation not a number.");
509: }
510:
511: value
512: value_lognot (arg1)
513: register value arg1;
514: {
1.1.1.2 root 515: COERCE_ENUM (arg1);
516:
1.1 root 517: if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
518: error ("Argument to complement operation not an integer.");
519:
520: return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
521: }
522:
523: static
524: initialize ()
525: {
526: }
527:
528: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.