Annotation of gdb/valarith.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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