Annotation of gdb/valarith.c, revision 1.1.1.3

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: 
1.1.1.3 ! root       30: value value_x_binop ();
        !            31: 
1.1       root       32: value
                     33: value_add (arg1, arg2)
                     34:        value arg1, arg2;
                     35: {
                     36:   register value val, valint, valptr;
                     37:   register int len;
                     38: 
                     39:   COERCE_ARRAY (arg1);
                     40:   COERCE_ARRAY (arg2);
                     41: 
                     42:   if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     43:        || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)
                     44:       &&
                     45:       (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT
                     46:        || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))
                     47:     /* Exactly one argument is a pointer, and one is an integer.  */
                     48:     {
                     49:       if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
                     50:        {
                     51:          valptr = arg1;
                     52:          valint = arg2;
                     53:        }
                     54:       else
                     55:        {
                     56:          valptr = arg2;
                     57:          valint = arg1;
                     58:        }
                     59:       len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));
                     60:       if (len == 0) len = 1;   /* For (void *) */
                     61:       val = value_from_long (builtin_type_long,
                     62:                             value_as_long (valptr)
                     63:                             + (len * value_as_long (valint)));
                     64:       VALUE_TYPE (val) = VALUE_TYPE (valptr);
                     65:       return val;
                     66:     }
                     67: 
1.1.1.3 ! root       68:   return value_x_binop (arg1, arg2, BINOP_ADD);
1.1       root       69: }
                     70: 
                     71: value
                     72: value_sub (arg1, arg2)
                     73:        value arg1, arg2;
                     74: {
                     75:   register value val;
                     76: 
                     77:   COERCE_ARRAY (arg1);
                     78:   COERCE_ARRAY (arg2);
                     79: 
                     80:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     81:       && 
                     82:       TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)
                     83:     {
                     84:       val = value_from_long (builtin_type_long,
                     85:                             value_as_long (arg1)
                     86:                             - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) * value_as_long (arg2));
                     87:       VALUE_TYPE (val) = VALUE_TYPE (arg1);
                     88:       return val;
                     89:     }
                     90: 
                     91:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR
                     92:       && 
                     93:       VALUE_TYPE (arg1) == VALUE_TYPE (arg2))
                     94:     {
                     95:       val = value_from_long (builtin_type_long,
                     96:                             (value_as_long (arg1) - value_as_long (arg2))
                     97:                             / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));
                     98:       return val;
                     99:     }
                    100: 
1.1.1.3 ! root      101:   return value_x_binop (arg1, arg2, BINOP_SUB);
1.1       root      102: }
                    103: 
                    104: /* Return the value of ARRAY[IDX].  */
                    105: 
                    106: value
                    107: value_subscript (array, idx)
                    108:      value array, idx;
                    109: {
                    110:   return value_ind (value_add (array, idx));
                    111: }
1.1.1.3 ! root      112: 
        !           113: /* Check to see if either argument is a structure.  If so, then
        !           114:    create an argument vector that calls arg1.operator @ (arg1,arg2)
        !           115:    and return that value (where '@' is any binary operator which
        !           116:    is legal for GNU C++).  If both args are scalar types then just
        !           117:    return value_binop().  */
        !           118: 
        !           119: value
        !           120: value_x_binop (arg1, arg2, op)
        !           121:      value arg1, arg2;
        !           122:      int op;
        !           123: {
        !           124:   value * argvec;
        !           125:   char *ptr;
        !           126:   char tstr[13];
        !           127:   
        !           128:   COERCE_ENUM (arg1);
        !           129:   COERCE_ENUM (arg2);
        !           130: 
        !           131:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
        !           132:       || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT)
        !           133:     {
        !           134:       /* now we know that what we have to do is construct our
        !           135:         arg vector and find the right function to call it with.  */
        !           136: 
        !           137:       if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
        !           138:        error ("friend functions not implemented yet");
1.1       root      139: 
1.1.1.3 ! root      140:       argvec = (value *) alloca (sizeof (value) * 4);
        !           141:       argvec[1] = value_addr (arg1);
        !           142:       argvec[2] = arg2;
        !           143:       argvec[3] = 0;
        !           144: 
        !           145:       /* make the right function name up */  
        !           146:       strcpy(tstr,"operator __");
        !           147:       ptr = tstr+9;
        !           148:       switch (op)
        !           149:        {
        !           150:        case BINOP_ADD: *ptr++ = '+'; *ptr = '\0'; break;
        !           151:        case BINOP_SUB: *ptr++ = '-'; *ptr = '\0'; break;
        !           152:        case BINOP_MUL: *ptr++ = '*'; *ptr = '\0'; break;
        !           153:        case BINOP_DIV: *ptr++ = '/'; *ptr = '\0'; break;
        !           154:        case BINOP_REM: *ptr++ = '%'; *ptr = '\0';break;
        !           155:        case BINOP_LSH: *ptr++ = '<'; *ptr = '<'; break;
        !           156:        case BINOP_RSH: *ptr++ = '>'; *ptr = '>'; break;
        !           157:        case BINOP_LOGAND:      *ptr++ = '&'; *ptr = '\0'; break;
        !           158:        case BINOP_LOGIOR:      *ptr++ = '|'; *ptr = '\0'; break;
        !           159:        case BINOP_LOGXOR:      *ptr++ = '^'; *ptr = '\0'; break;
        !           160:        case BINOP_AND: *ptr++ = '&'; *ptr = '&'; break;
        !           161:        case BINOP_OR:  *ptr++ = '|'; *ptr = '|'; break;
        !           162:        case BINOP_MIN: *ptr++ = '<'; *ptr = '?'; break;
        !           163:        case BINOP_MAX: *ptr++ = '>'; *ptr = '?'; break;
        !           164:        default:
        !           165:          error ("Invalid binary operation specified.");
        !           166:        }
        !           167:       argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
        !           168:       if (argvec[0])
        !           169:        return call_function (argvec[0], 2, argvec + 1);
        !           170:       else error ("member function %s not found", tstr);
        !           171:     }
        !           172: 
        !           173:   return value_binop(arg1, arg2, op);
        !           174: }
        !           175: 
1.1       root      176: /* Perform a binary operation on two integers or two floats.
                    177:    Does not support addition and subtraction on pointers;
                    178:    use value_add or value_sub if you want to handle those possibilities.  */
                    179: 
                    180: value
                    181: value_binop (arg1, arg2, op)
                    182:      value arg1, arg2;
                    183:      int op;
                    184: {
                    185:   register value val;
                    186: 
1.1.1.2   root      187:   COERCE_ENUM (arg1);
                    188:   COERCE_ENUM (arg2);
                    189: 
1.1       root      190:   if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT
                    191:        &&
                    192:        TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    193:       ||
                    194:       (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT
                    195:        &&
                    196:        TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT))
                    197:     error ("Argument to arithmetic operation not a number.");
                    198: 
                    199:   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT
                    200:       ||
                    201:       TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT)
                    202:     {
                    203:       double v1, v2, v;
                    204:       v1 = value_as_double (arg1);
                    205:       v2 = value_as_double (arg2);
                    206:       switch (op)
                    207:        {
                    208:        case BINOP_ADD:
                    209:          v = v1 + v2;
                    210:          break;
                    211: 
                    212:        case BINOP_SUB:
                    213:          v = v1 - v2;
                    214:          break;
                    215: 
                    216:        case BINOP_MUL:
                    217:          v = v1 * v2;
                    218:          break;
                    219: 
                    220:        case BINOP_DIV:
                    221:          v = v1 / v2;
                    222:          break;
                    223: 
                    224:        default:
                    225:          error ("Integer-only operation on floating point number.");
                    226:        }
                    227: 
                    228:       val = allocate_value (builtin_type_double);
                    229:       *(double *) VALUE_CONTENTS (val) = v;
                    230:     }
                    231:   else
                    232:     {
                    233:       long v1, v2, v;
                    234:       v1 = value_as_long (arg1);
                    235:       v2 = value_as_long (arg2);
                    236: 
                    237:       switch (op)
                    238:        {
                    239:        case BINOP_ADD:
                    240:          v = v1 + v2;
                    241:          break;
                    242: 
                    243:        case BINOP_SUB:
                    244:          v = v1 - v2;
                    245:          break;
                    246: 
                    247:        case BINOP_MUL:
                    248:          v = v1 * v2;
                    249:          break;
                    250: 
                    251:        case BINOP_DIV:
                    252:          v = v1 / v2;
                    253:          break;
                    254: 
                    255:        case BINOP_REM:
                    256:          v = v1 % v2;
                    257:          break;
                    258: 
                    259:        case BINOP_LSH:
                    260:          v = v1 << v2;
                    261:          break;
                    262: 
                    263:        case BINOP_RSH:
                    264:          v = v1 >> v2;
                    265:          break;
                    266: 
                    267:        case BINOP_LOGAND:
                    268:          v = v1 & v2;
                    269:          break;
                    270: 
                    271:        case BINOP_LOGIOR:
                    272:          v = v1 | v2;
                    273:          break;
                    274: 
                    275:        case BINOP_LOGXOR:
                    276:          v = v1 ^ v2;
                    277:          break;
                    278: 
                    279:        case BINOP_AND:
                    280:          v = v1 && v2;
                    281:          break;
                    282: 
                    283:        case BINOP_OR:
                    284:          v = v1 || v2;
                    285:          break;
                    286: 
1.1.1.3 ! root      287:        case BINOP_MIN:
        !           288:          v = v1 < v2 ? v1 : v2;
        !           289:          break;
        !           290: 
        !           291:        case BINOP_MAX:
        !           292:          v = v1 > v2 ? v1 : v2;
        !           293:          break;
        !           294: 
1.1       root      295:        default:
                    296:          error ("Invalid binary operation on numbers.");
                    297:        }
                    298: 
                    299:       val = allocate_value (builtin_type_long);
                    300:       *(long *) VALUE_CONTENTS (val) = v;
                    301:     }
                    302: 
                    303:   return val;
                    304: }
                    305: 
                    306: /* Simulate the C operator ! -- return 1 if ARG1 contains zeros.  */
                    307: 
                    308: int
                    309: value_zerop (arg1)
                    310:      value arg1;
                    311: {
                    312:   register int len;
                    313:   register char *p;
                    314: 
                    315:   COERCE_ARRAY (arg1);
                    316: 
                    317:   len = TYPE_LENGTH (VALUE_TYPE (arg1));
                    318:   p = VALUE_CONTENTS (arg1);
                    319: 
                    320:   while (--len >= 0)
                    321:     {
                    322:       if (*p++)
                    323:        break;
                    324:     }
                    325: 
                    326:   return len < 0;
                    327: }
                    328: 
                    329: /* Simulate the C operator == by returning a 1
                    330:    iff ARG1 and ARG2 have equal contents.  */
                    331: 
                    332: int
                    333: value_equal (arg1, arg2)
                    334:      register value arg1, arg2;
                    335: 
                    336: {
                    337:   register int len;
                    338:   register char *p1, *p2;
                    339:   enum type_code code1;
                    340:   enum type_code code2;
                    341: 
                    342:   COERCE_ARRAY (arg1);
                    343:   COERCE_ARRAY (arg2);
                    344: 
                    345:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    346:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    347: 
                    348:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    349:     return value_as_long (arg1) == value_as_long (arg2);
                    350:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    351:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    352:     return value_as_double (arg1) == value_as_double (arg2);
                    353:   else if ((code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
                    354:           || (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT))
                    355:     return value_as_long (arg1) == value_as_long (arg2);
                    356:   else if (code1 == code2
                    357:           && ((len = TYPE_LENGTH (VALUE_TYPE (arg1)))
                    358:               == TYPE_LENGTH (VALUE_TYPE (arg2))))
                    359:     {
                    360:       p1 = VALUE_CONTENTS (arg1);
                    361:       p2 = VALUE_CONTENTS (arg2);
                    362:       while (--len >= 0)
                    363:        {
                    364:          if (*p1++ != *p2++)
                    365:            break;
                    366:        }
                    367:       return len < 0;
                    368:     }
                    369:   else
                    370:     error ("Invalid type combination in equality test.");
                    371: }
                    372: 
                    373: /* Simulate the C operator < by returning 1
                    374:    iff ARG1's contents are less than ARG2's.  */
                    375: 
                    376: int
                    377: value_less (arg1, arg2)
                    378:      register value arg1, arg2;
                    379: {
                    380:   register enum type_code code1;
                    381:   register enum type_code code2;
                    382: 
                    383:   COERCE_ARRAY (arg1);
                    384:   COERCE_ARRAY (arg2);
                    385: 
                    386:   code1 = TYPE_CODE (VALUE_TYPE (arg1));
                    387:   code2 = TYPE_CODE (VALUE_TYPE (arg2));
                    388: 
                    389:   if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
                    390:     return value_as_long (arg1) < value_as_long (arg2);
                    391:   else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
                    392:           && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
                    393:     return value_as_double (arg1) < value_as_double (arg2);
                    394:   else if ((code1 == TYPE_CODE_PTR || code1 == TYPE_CODE_INT)
                    395:           && (code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_INT))
                    396:     return value_as_long (arg1) < value_as_long (arg2);
                    397:   else
                    398:     error ("Invalid type combination in ordering comparison.");
                    399: }
                    400: 
                    401: /* The unary operators - and ~.  Both free the argument ARG1.  */
                    402: 
                    403: value
                    404: value_neg (arg1)
                    405:      register value arg1;
                    406: {
1.1.1.2   root      407:   register struct type *type;
                    408: 
                    409:   COERCE_ENUM (arg1);
                    410: 
                    411:   type = VALUE_TYPE (arg1);
1.1       root      412: 
                    413:   if (TYPE_CODE (type) == TYPE_CODE_FLT)
                    414:     return value_from_double (type, - value_as_double (arg1));
                    415:   else if (TYPE_CODE (type) == TYPE_CODE_INT)
                    416:     return value_from_long (type, - value_as_long (arg1));
                    417:   else
                    418:     error ("Argument to negate operation not a number.");
                    419: }
                    420: 
                    421: value
                    422: value_lognot (arg1)
                    423:      register value arg1;
                    424: {
1.1.1.2   root      425:   COERCE_ENUM (arg1);
                    426: 
1.1       root      427:   if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT)
                    428:     error ("Argument to complement operation not an integer.");
                    429: 
                    430:   return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1));
                    431: }
                    432: 
                    433: static
                    434: initialize ()
                    435: {
                    436: }
                    437: 
                    438: END_FILE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.