Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom.ansi / ch3.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: ch3.c,v 1.30 1994/06/27 07:58:29 ceriel Exp $ */
6 /*      S E M A N T I C   A N A L Y S I S -- C H A P T E R  3.3         */
7
8 #include        "debug.h"
9 #include        "lint.h"
10 #include        "nobitfield.h"
11 #include        "idf.h"
12 #include        <flt_arith.h>
13 #include        "arith.h"
14 #include        "proto.h"
15 #include        "type.h"
16 #include        "struct.h"
17 #include        "label.h"
18 #include        "expr.h"
19 #include        "def.h"
20 #include        "Lpars.h"
21 #include        "assert.h"
22 #include        "file_info.h"
23
24 extern char options[];
25 extern char *symbol2str();
26 extern struct type *qualifier_type();
27
28 /*      Most expression-handling routines have a pointer to a
29         (struct type *) as first parameter. The object under the pointer
30         gets updated in the process.
31 */
32
33 ch3sel(expp, oper, idf)
34         struct expr **expp;
35         struct idf *idf;
36 {
37         /*      The selector idf is applied to *expp; oper may be '.' or
38                 ARROW.
39         */
40         register struct expr *exp;
41         register struct type *tp;
42         register struct sdef *sd;
43
44         any2opnd(expp, oper);
45         exp = *expp;
46         tp = exp->ex_type;
47         if (oper == ARROW)      {
48                 if (tp->tp_fund == POINTER &&
49                     ( tp->tp_up->tp_fund == STRUCT ||
50                       tp->tp_up->tp_fund == UNION))     /* normal case */
51                         tp = tp->tp_up;
52                 else {  /* constructions like "12->selector" and
53                                 "char c; c->selector"
54                         */
55                         switch (tp->tp_fund)    {
56                         case POINTER:
57                                 break;
58                         case INT:
59                         case LONG:
60                                 /* An error is given in idf2sdef() */
61                                 ch3cast(expp, CAST, pa_type);
62                                 sd = idf2sdef(idf, tp);
63                                 tp = sd->sd_stype;
64                                 break;
65                         default:
66                                 expr_error(exp, "-> applied to %s",
67                                         symbol2str(tp->tp_fund));
68                         case ERRONEOUS:
69                                 exp->ex_type = error_type;
70                                 return;
71                         }
72                 }
73         } else {                /* oper == '.' */
74                 /* nothing */
75         }
76         exp = *expp;
77         switch (tp->tp_fund)    {
78         case POINTER:   /* for int *p;  p->next = ...   */
79         case STRUCT:
80         case UNION:
81                 break;
82         case INT:
83         case LONG:
84                 /* warning will be given by idf2sdef() */
85                 break;
86         default:
87                 if (!is_anon_idf(idf))
88                         expr_error(exp, "selector %s applied to %s",
89                                 idf->id_text, symbol2str(tp->tp_fund));
90         case ERRONEOUS:
91                 exp->ex_type = error_type;
92                 return;
93         }
94         sd = idf2sdef(idf, tp);
95         if (oper == '.')        {
96                 /*      there are 3 cases in which the selection can be
97                         performed compile-time: 
98                         I:      n.sel (n either an identifier or a constant)
99                         II:     (e.s1).s2 (transformed into (e.(s1+s2)))
100                         III:    (e->s1).s2 (transformed into (e->(s1+s2)))
101                                 The code performing these conversions is
102                                 extremely obscure.
103                 */
104                 if (exp->ex_class == Value)     {
105                         /*      It is an object we know the address of; so
106                                 we can calculate the address of the
107                                 selected member 
108                         */
109                         exp->VL_VALUE += sd->sd_offset;
110                         exp->ex_type = sd->sd_type;
111                         exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
112                         if (exp->ex_type == error_type) {
113                                 exp->ex_flags |= EX_ERROR;
114                         }
115                 }
116                 else
117                 if (exp->ex_class == Oper)      {
118                         struct oper *op = &(exp->ex_object.ex_oper);
119                         
120                         if (op->op_oper == '.' || op->op_oper == ARROW) {
121                                 ASSERT(is_cp_cst(op->op_right));
122                                 op->op_right->VL_VALUE += sd->sd_offset;
123                                 exp->ex_type = sd->sd_type;
124                                 exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
125                                 if (exp->ex_type == error_type) {
126                                         exp->ex_flags |= EX_ERROR;
127                                 }
128                         }
129                         else {
130                                 exp = new_oper(sd->sd_type, exp, '.',
131                                                 intexpr(sd->sd_offset, INT));
132                                 exp->ex_lvalue = sd->sd_type->tp_fund != ARRAY;
133                                 if (!exp->OP_LEFT->ex_lvalue)
134                                         exp->ex_flags |= EX_ILVALUE;
135                         }
136                 }
137         }
138         else { /* oper == ARROW */
139                 if (is_ld_cst(exp)) {
140                         exp->VL_VALUE += sd->sd_offset;
141                         exp->ex_type = sd->sd_type;
142                 }
143                 else  {
144                         exp = new_oper(sd->sd_type,
145                                 exp, oper, intexpr(sd->sd_offset, INT));
146                 }
147                 exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
148                 exp->ex_flags &= ~EX_ILVALUE;
149         }
150         if ((sd->sd_type->tp_typequal & TQ_CONST)
151             || (tp->tp_typequal & TQ_CONST))
152                 exp->ex_flags |= EX_READONLY;
153         if ((sd->sd_type->tp_typequal & TQ_VOLATILE)
154             || (tp->tp_typequal & TQ_VOLATILE))
155                 exp->ex_flags |= EX_VOLATILE;
156         if (oper == '.' && exp->ex_flags & EX_READONLY)  {
157                 exp->ex_type = qualifier_type(exp->ex_type, TQ_CONST);
158         }
159         if (exp->ex_flags & EX_VOLATILE)  {
160                 exp->ex_type = qualifier_type(exp->ex_type, TQ_VOLATILE);
161         }
162         *expp = exp;
163 }
164
165 ch3incr(expp, oper)
166         struct expr **expp;
167 {
168         /*      The monadic prefix/postfix incr/decr operator oper is
169                 applied to *expp.
170         */
171         ch3asgn(expp, oper, intexpr((arith)1, INT));
172 }
173
174 ch3cast(expp, oper, tp)
175         register struct expr **expp;
176         register struct type *tp;
177 {
178         /*      The expression *expp is cast to type tp; the cast is
179                 caused by the operator oper.  If the cast has
180                 to be passed on to run time, its left operand will be an
181                 expression of class Type.
182         */
183         register struct type *oldtp;
184         register struct expr *exp = *expp;
185         int qual_lev, ascompat = 0;
186
187         if (oper == RETURN && tp->tp_fund == VOID) {
188                 expr_strict(exp, "return <expression> in function returning void");
189                 exp->ex_type = void_type;
190                 return;
191         }
192         if (exp->ex_type->tp_fund == FUNCTION) {
193                 function2pointer(exp);
194         }
195         if (exp->ex_type->tp_fund == ARRAY)
196                 array2pointer(exp);
197         if (exp->ex_class == String)
198                 string2pointer(exp);
199         oldtp = exp->ex_type;
200
201         if (oldtp->tp_size <= 0 && oldtp->tp_fund != VOID) {
202                 expr_error(exp,"incomplete type in expression");
203         }
204
205 #ifndef NOBITFIELD
206         if (oldtp->tp_fund == FIELD)    {
207                 field2arith(expp);
208                 ch3cast(expp, oper, tp);
209                 return;
210         }
211         if (tp->tp_fund == FIELD) {
212                 ch3cast(expp, oper, tp->tp_up);
213                 return;
214         }
215 #endif /* NOBITFIELD */
216         switch (oper) {
217         default:        qual_lev = -1; break;
218         case CAST:      qual_lev = -999; break;         /* ??? hack */
219         case CASTAB:
220         case '=':
221         case RETURN:    ascompat = 1;           /* assignment compatibility */
222                 /* fallthrough */
223         case '-':
224         case '<':
225         case '>':
226         case LESSEQ:
227         case GREATEREQ:
228         case EQUAL:
229         case NOTEQUAL:
230         case ':':
231                         qual_lev = -2;
232                         break;
233         }
234
235         if (equal_type(tp, oldtp, qual_lev, 0)) {
236                 /* life is easy */
237                 if (ascompat && tp->tp_fund == POINTER) {
238                         if ((tp->tp_up->tp_typequal & oldtp->tp_up->tp_typequal)
239                             != oldtp->tp_up->tp_typequal) {
240                                 expr_strict( exp, "qualifier error");
241                         }
242                 }
243                 exp->ex_type = tp;      /* so qualifiers are allright */
244         }
245         else
246         if (tp->tp_fund == VOID) {
247                 /* easy again */
248                 exp->ex_type = void_type;
249         }
250         else
251         if (is_arith_type(oldtp) && is_arith_type(tp))  {
252                 int oldi = is_integral_type(oldtp);
253                 int i = is_integral_type(tp);
254
255                 if (oldi && i)  {
256 #ifdef  LINT
257                         if (oper == CAST)
258                                 exp->ex_type = tp;
259                         else {
260                                 int2int(expp, tp);
261                         }
262 #else   /* LINT */
263                         int2int(expp, tp);
264 #endif  /* LINT */
265                 }
266                 else
267                 if (oldi && !i) {
268 #ifdef  LINT
269                         if (oper == CAST)
270                                 exp->ex_type = tp;
271                         else {
272                                 int2float(expp, tp);
273                         }
274 #else   /* LINT */
275                         int2float(expp, tp);
276 #endif  /* LINT */
277                 }
278                 else
279                 if (!oldi && i) {
280 #ifdef  LINT
281                         if (oper == CAST)
282                                 exp->ex_type = tp;
283                         else {
284                                 float2int(expp, tp);
285                         }
286 #else   /* LINT */
287                         float2int(expp, tp);
288 #endif  /* LINT */
289                 }
290                 else {
291                         /* !oldi && !i */
292 #ifdef  LINT
293                         if (oper == CAST)
294                                 exp->ex_type = tp;
295                         else {
296                                 float2float(expp, tp);
297                         }
298 #else   /* LINT */
299                         float2float(expp, tp);
300 #endif  /* LINT */
301                 }
302         }
303         else
304         if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER)        {
305                 switch (oper) {
306                 case EQUAL:
307                 case NOTEQUAL:
308                 case '=':
309                 case CASTAB:
310                 case RETURN:
311                 case ':':
312                     if (tp->tp_up && oldtp->tp_up) {
313                             if (tp->tp_up->tp_fund == VOID
314                                 && oldtp->tp_up->tp_fund != FUNCTION) {
315                                 break;  /* switch */
316                             }
317                             if (oldtp->tp_up->tp_fund == VOID
318                                 && tp->tp_up->tp_fund != FUNCTION) {
319                                 break;  /* switch */
320                             }
321                             if (oldtp->tp_up->tp_fund == VOID
322                                 && is_cp_cst(exp)
323                                 && exp->VL_VALUE == (arith)0)
324                                 break;  /* switch */
325                     }
326                     /* falltrough */
327                 default:
328                     if (oper == CASTAB)
329                             expr_strict(exp, "incompatible pointers in call");
330                     else
331                             expr_strict(exp, "incompatible pointers in %s",
332                                                         symbol2str(oper));
333                     break;
334                 case CAST: break;
335                 }
336 #ifdef  LINT
337                 if (oper != CAST)
338                         lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
339 #endif  /* LINT */
340                 exp->ex_type = tp;      /* free conversion */
341         }
342         else
343         if (oldtp->tp_fund == POINTER && is_integral_type(tp))  {
344                 /* from pointer to integral */
345                 if (oper != CAST)
346                         expr_strict(exp,
347                                 "illegal conversion of pointer to %s",
348                                 symbol2str(tp->tp_fund));
349                 if (oldtp->tp_size > tp->tp_size)
350                         expr_warning(exp,
351                                 "conversion of pointer to %s loses accuracy",
352                                 symbol2str(tp->tp_fund));
353                 if (oldtp->tp_size != tp->tp_size) {
354                         int2int(expp, tp);
355                 } else
356                         exp->ex_type = tp;
357         }
358         else
359         if (tp->tp_fund == POINTER && is_integral_type(oldtp))  {
360                 /* from integral to pointer */
361                 switch (oper)   {
362                 case CAST:
363                         break;
364                 case CASTAB:
365                 case EQUAL:
366                 case NOTEQUAL:
367                 case '=':
368                 case RETURN:
369                         if (is_cp_cst(exp) && exp->VL_VALUE == (arith)0)
370                                 break;
371                 default:
372                         expr_strict(exp,
373                                 "illegal conversion of %s to pointer",
374                                 symbol2str(oldtp->tp_fund));
375                         break;
376                 }
377                 if (oldtp->tp_size > tp->tp_size)
378                         expr_warning(exp,
379                                 "conversion of %s to pointer loses accuracy",
380                                 symbol2str(oldtp->tp_fund));
381                 if (oldtp->tp_size != tp->tp_size) {
382                         int2int(expp, tp);
383                 } else
384                         exp->ex_type = tp;
385         }
386         else
387         if (oldtp->tp_fund == ERRONEOUS) {
388                 /* we just won't look */
389                 exp->ex_type = tp;      /* brute force */
390         }
391         else
392         if (oldtp->tp_size == tp->tp_size && oper == CAST)      {
393                 expr_strict(exp, "dubious conversion based on equal size");
394                 exp->ex_type = tp;              /* brute force */
395         }
396         else    {
397                 if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS)
398                         expr_error(exp, "cannot convert %s to %s",
399                                         symbol2str(oldtp->tp_fund),
400                                         symbol2str(tp->tp_fund)
401                                     );
402                 exp->ex_type = tp;              /* brute force */
403         }
404         /* re-initialize exp, since *expp may have changed */
405         exp = *expp;
406         if (oper == CAST) {
407                 exp->ex_flags |= EX_ILVALUE;
408         }
409 }
410
411 /*      Determine whether two types are equal.
412 */
413 equal_type(tp, otp, qual_lev, diag)
414         register struct type *tp, *otp;
415         int qual_lev, diag;
416 {
417          if (tp == otp)
418                 return 1;
419         if (!tp
420             || !otp
421             || (tp->tp_fund != otp->tp_fund)
422             || (tp->tp_unsigned != otp->tp_unsigned)
423             || (tp->tp_align != otp->tp_align))
424                 return 0;
425         if (tp->tp_size != otp->tp_size) {
426                 if (tp->tp_fund != ARRAY
427                     || (tp->tp_size != -1 && otp->tp_size != -1))
428                         return 0;
429         }
430
431         if (qual_lev >= 0 && tp->tp_typequal != otp->tp_typequal) {
432                 strict("missing or illegal qualifiers");
433         }
434
435         switch (tp->tp_fund) {
436
437         case FUNCTION:
438                 /*      If both types have parameter type lists, the type of
439                         each parameter in the composite parameter type list
440                         is the composite type of the corresponding paramaters.
441                 */
442                 if (tp->tp_proto && otp->tp_proto) {
443                         if (!equal_proto(tp->tp_proto, otp->tp_proto, diag))
444                                 return 0;
445                 } else if (tp->tp_proto || otp->tp_proto) {
446                         if (!legal_mixture(tp, otp, diag))
447                                 return 0;
448                 }
449                 return equal_type(tp->tp_up, otp->tp_up, qual_lev + 1, diag);
450
451         case ARRAY:
452                 /*      If one type is an array of known size, the composite
453                         type is an array of that size
454                 */
455                 if (tp->tp_size != otp->tp_size &&
456                      (tp->tp_size != -1 && otp->tp_size != -1))
457                         return 0;
458                 return equal_type(tp->tp_up, otp->tp_up, qual_lev/* ??? +1 */, diag);
459
460         case POINTER:
461                 return equal_type(tp->tp_up, otp->tp_up, qual_lev + 1, diag);
462
463         case FIELD:
464                 return equal_type(tp->tp_up, otp->tp_up, qual_lev/* ??? +1 */, diag);
465
466         case STRUCT:
467         case UNION:
468         case ENUM:
469                 return tp->tp_idf == otp->tp_idf && tp->tp_sdef == otp->tp_sdef;
470
471         default:
472                 return 1;
473         }
474 }
475
476 check_pseudoproto(pl, opl, diag)
477         register struct proto *pl, *opl;
478 {
479         int retval = 1;
480
481         if (pl->pl_flag & PL_ELLIPSIS) {
482                 if (diag) {     
483                         error("illegal ellipsis terminator");
484                         pl->pl_flag |= PL_ERRGIVEN;
485                         opl->pl_flag |= PL_ERRGIVEN;
486                 }
487                 return 0;
488         }
489         if (opl->pl_flag & PL_VOID) {
490                 if (!(pl->pl_flag & PL_VOID)) {
491                         if (diag) {
492                                 strict("function is defined without parameters");
493                         }
494                         return 0;
495                 }
496                 return 1;
497         }
498         while (pl && opl) {
499             if (!equal_type(pl->pl_type, opl->pl_type, -1, diag)) {
500                 if (diag) {
501                         if (!(pl->pl_flag & PL_ERRGIVEN)
502                             && !(opl->pl_flag & PL_ERRGIVEN))
503                                 error("incorrect type for parameter %s of definition",
504                                         opl->pl_idf->id_text);
505                         pl->pl_flag |= PL_ERRGIVEN;
506                         opl->pl_flag |= PL_ERRGIVEN;
507                 }
508                 retval = 0;
509             }
510             pl = pl->next;
511             opl = opl->next;
512         }
513         if (pl || opl) {
514                 if (diag) error("incorrect number of parameters");
515                 retval = 0;
516         }
517         return retval;
518 }
519
520 legal_mixture(tp, otp, diag)
521         struct type *tp, *otp;
522         int diag;
523 {
524         struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
525         int retval = 1;
526         register struct proto *prot;
527         int fund;
528
529         ASSERT( (pl != 0) ^ (opl != 0));
530         if (pl)  {
531                 prot = pl;
532         } else  {
533                 prot = opl;
534         }
535         if (!opl && otp->tp_pseudoproto) {
536                 return check_pseudoproto(tp->tp_proto, otp->tp_pseudoproto, diag);
537         }
538
539         if (prot->pl_flag & PL_ELLIPSIS) {
540                 if (prot->pl_flag & PL_ERRGIVEN) {
541                         if (pl)
542                                 error("illegal ellipsis terminator");
543                         else    error("ellipsis terminator in previous (prototype) declaration");
544                         prot->pl_flag |= PL_ERRGIVEN;
545                 }
546                 return 0;
547         }
548         while (prot) {
549                                 /* if (!(prot->pl_flag & PL_ELLIPSIS)) {} */
550                 fund = prot->pl_type->tp_fund;
551                 if (fund == CHAR || fund == SHORT || fund == FLOAT) {
552                         if (diag && !(prot->pl_flag & PL_ERRGIVEN))
553                             error("illegal %s parameter in %sdeclaration",
554                                 symbol2str(fund), (opl ? "previous (prototype) " : "" ));
555                         prot->pl_flag |= PL_ERRGIVEN;
556                         retval = 0;
557                 }
558                 prot = prot->next;
559         }
560         return retval;
561 }
562
563 equal_proto(pl, opl, diag)
564         register struct proto *pl, *opl;
565         int diag;
566 {
567         if (pl == opl)
568                 return 1;
569
570         /*      If only one type is a function type with a parameter type list
571                 (a function prototype), the composite type is a function
572                 prototype with parameter type list.
573         */
574         while ( pl && opl) {
575
576             if ((pl->pl_flag & ~PL_ERRGIVEN) != (opl->pl_flag & ~PL_ERRGIVEN) ||
577                 !equal_type(pl->pl_type, opl->pl_type, -1, diag))
578                 return 0;
579
580             pl = pl->next;
581             opl = opl->next;
582         }
583         return !(pl || opl);
584 }
585
586 /* check if a type has a consqualified member */
587 recurqual(tp, qual)
588 struct type *tp;
589 int qual;
590 {
591         register struct sdef *sdf;
592
593         ASSERT(tp);
594
595         if (tp->tp_typequal & qual) return 1;
596         switch(tp->tp_fund) {
597         case UNION:
598         case STRUCT:
599         case ENUM:
600                 sdf = tp->tp_sdef;
601                 while (sdf) {
602                         if (recurqual(sdf->sd_type, qual))
603                                 return 1;
604                         sdf = sdf->sd_sdef;
605                 }
606                 break;
607         }
608         return 0;
609 }
610
611 ch3asgn(expp, oper, expr)
612         struct expr **expp;
613         struct expr *expr;
614 {
615         /*      The assignment operators.
616                 "f op= e" should be interpreted as
617                 "f = (typeof f)((typeof (f op e))f op (typeof (f op e))e)"
618                 and not as "f = f op (typeof f)e".
619                 Consider, for example, (i == 10) i *= 0.9; (i == 9), where
620                 typeof i == int.
621                 The resulting expression tree becomes:
622                                 op=
623                                 / \
624                                /   \
625                               f     (typeof (f op e))e
626                 EVAL should however take care of evaluating (typeof (f op e))f
627         */
628         register struct expr *exp = *expp;
629         int fund = exp->ex_type->tp_fund;
630         struct type *tp;
631         char *oper_string = symbol2str(oper);
632
633         /* We expect an lvalue */
634         if (fund == ARRAY || fund == FUNCTION) exp->ex_lvalue = 0;
635         if (!exp->ex_lvalue) {
636                 expr_error(exp, "no lvalue in operand of %s", oper_string);
637         } else if (exp->ex_flags & EX_ILVALUE)  {
638                 expr_strict(exp, "incorrect lvalue in operand of %s", oper_string);
639         } else if (exp->ex_flags & EX_READONLY) {
640                 expr_error(exp, "operand of %s is read-only", oper_string);
641         } else if (fund == STRUCT || fund == UNION) {
642                 if (recurqual(exp->ex_type, TQ_CONST))
643                         expr_error(exp,"operand of %s contains a const-qualified member",
644                                             oper_string);
645         }
646
647         if (oper == '=') {
648                 ch3cast(&expr, oper, exp->ex_type);
649                 tp = expr->ex_type;
650         }
651         else {  /* turn e into e' where typeof(e') = typeof (f op e) */
652                 struct expr *extmp = intexpr((arith)0, INT);
653
654                 /* this is really $#@&*%$# ! */
655                 /* if you correct this, please correct lint_new_oper() too */
656                 extmp->ex_lvalue = 1;
657                 extmp->ex_type = exp->ex_type;
658                 ch3bin(&extmp, oper, expr);
659                 /* Note that ch3bin creates a tree of the expression
660                         ((typeof (f op e))f op (typeof (f op e))e),
661                    where f ~ extmp and e ~ expr.
662                    We want to use (typeof (f op e))e.
663                    Ch3bin does not create a tree if both operands
664                    were illegal or constants!
665                 */
666                 tp = extmp->ex_type;    /* perform the arithmetic in type tp */
667                 if (extmp->ex_class == Oper) {
668                         expr = extmp->OP_RIGHT;
669                         extmp->OP_RIGHT = NILEXPR;
670                         free_expression(extmp);
671                 }
672                 else
673                         expr = extmp;
674         }
675 #ifndef NOBITFIELD
676         exp = new_oper(fund == FIELD ? exp->ex_type->tp_up : exp->ex_type,
677                 exp, oper, expr);
678 #else /* NOBITFIELD */
679         exp = new_oper(exp->ex_type, exp, oper, expr);
680 #endif /* NOBITFIELD */
681         exp->OP_TYPE = tp;      /* for EVAL() */
682         exp->ex_flags |= EX_SIDEEFFECTS;
683         *expp = exp;
684 }
685
686 /*      Some interesting (?) questions answered.
687 */
688 int
689 is_integral_type(tp)
690         register struct type *tp;
691 {
692         switch (tp->tp_fund)    {
693         case CHAR:
694         case SHORT:
695         case INT:
696         case LONG:
697         case ENUM:
698                 return 1;
699 #ifndef NOBITFIELD
700         case FIELD:
701                 return is_integral_type(tp->tp_up);
702 #endif /* NOBITFIELD */
703         default:
704                 return 0;
705         }
706 }
707
708 int
709 is_arith_type(tp)
710         register struct type *tp;
711 {
712         switch (tp->tp_fund)    {
713         case CHAR:
714         case SHORT:
715         case INT:
716         case LONG:
717         case ENUM:
718         case FLOAT:
719         case DOUBLE:
720         case LNGDBL:
721                 return 1;
722 #ifndef NOBITFIELD
723         case FIELD:
724                 return is_arith_type(tp->tp_up);
725 #endif /* NOBITFIELD */
726         default:
727                 return 0;
728         }
729 }