|
|
1.1 root 1: *** /tmp/,RCSt1a12477 Tue Nov 7 09:42:18 1989
2: --- /tmp/,RCSt2a12477 Tue Nov 7 09:42:22 1989
3: ***************
4: *** 2,8 ****
5: /*ident "@(#)ctrans:src/expr3.c 1.3.5.29" */
6: /*
7: $Source: /usr3/lang/benson/work/stripped_cfront/O/RCS/expr3.c,v $ $RCSfile: expr3.c,v $
8: ! $Revision: 1.8 $ $Date: 89/10/16 08:15:27 $
9: $Author: benson $ $Locker: $
10: $State: Exp $
11: */
12: --- 2,8 ----
13: /*ident "@(#)ctrans:src/expr3.c 1.3.5.29" */
14: /*
15: $Source: /usr3/lang/benson/work/stripped_cfront/O/RCS/expr3.c,v $ $RCSfile: expr3.c,v $
16: ! $Revision: 1.9 $ $Date: 89/10/20 14:30:34 $
17: $Author: benson $ $Locker: $
18: $State: Exp $
19: */
20: ***************
21: *** 24,29 ****
22: --- 24,30 ----
23:
24: #include "cfront.h"
25: #include "size.h"
26: + #include "extended_error.h"
27:
28: int pr_dominate(Ptype t1, Ptype t2)
29: /*
30: ***************
31: *** 246,252 ****
32:
33: Pname Ntmp;
34:
35: ! static refd; // initialization routine called by ref_init, do not apply itor
36: extern loc no_where;
37:
38: Pname make_tmp(char c, Ptype t, Ptable tbl)
39: --- 247,253 ----
40:
41: Pname Ntmp;
42:
43: ! int refd; // initialization routine called by ref_init, do not apply itor
44: extern loc no_where;
45:
46: Pname make_tmp(char c, Ptype t, Ptable tbl)
47: ***************
48: *** 889,900 ****
49:
50: }
51:
52: - extern int type_indexable (Ptype, int);
53: extern Pname indexable_member_reference (Pexpr, int);
54:
55: void const_err (Ptype t, Pexpr ob, Pname fn)
56: {
57: ! int tpindexable = type_indexable(t, 1);
58: int topindex = (indexable_member_reference(ob, 0) != 0);
59: if(!tpindexable)
60: error(strict_opt?0:'w',"non-constMF%n called for constO",fn);
61: --- 890,901 ----
62:
63: }
64:
65: extern Pname indexable_member_reference (Pexpr, int);
66:
67: void const_err (Ptype t, Pexpr ob, Pname fn)
68: {
69: ! int tpindexable = t->tconst(const_idx) && !t->tconst(const_not_idx);
70: !
71: int topindex = (indexable_member_reference(ob, 0) != 0);
72: if(!tpindexable)
73: error(strict_opt?0:'w',"non-constMF%n called for constO",fn);
74: ***************
75: *** 911,917 ****
76: --- 912,983 ----
77: }
78:
79:
80: + class call_fct_eei {
81: + public:
82: + int valid; /* not on until we are processing some argument or another */
83: + Pname fname;
84: + Pname cur_formal;
85: + Pexpr cur_actual;
86: + int argx;
87: + call_fct_eei () {
88: + valid = 0;
89: + argx = 0;
90: + fname = 0;
91: + cur_formal = 0;
92: + cur_actual = 0;
93: + };
94: + };
95: +
96: + int unprintable_expression_p (Pexpr e);
97: + char * print_expression (Pexpr e, int flags, int& err);
98: +
99: + void call_fct_extended_error (void * info, FILE * of)
100: + {
101: + call_fct_eei& cfe = *(call_fct_eei *) info;
102: +
103: + if(!cfe.valid) return;
104: + if(cfe.fname) fprintf(of, "Calling %s; ", err::name_string (cfe.fname));
105: + if(cfe.cur_actual) {
106: + int perr = 0;
107: + char * msg;
108: + if(!unprintable_expression_p(cfe.cur_actual))
109: + msg = print_expression (cfe.cur_actual, 0, perr);
110: + else perr = 1;
111: + if(perr)
112: + fprintf(of, "Passing an expression ");
113: + else fprintf(of, "Passing %s ", msg);
114: + if(msg) free (msg);
115: + }
116: + if(cfe.cur_formal) {
117: + if(cfe.cur_formal->string)
118: + fprintf(of, "to %s ", err::name_string(cfe.cur_formal));
119: + else fprintf(of, "to type %s ", err::type_string(cfe.cur_formal->tp));
120: + }
121: + fprintf(of, "\n");
122: + }
123: +
124: + class call_fct_undo : public basic_undo {
125: + public:
126: + extended_error_state * ees;
127: + call_fct_eei cfei;
128: + call_fct_undo () {
129: + ees = extended_error_state::push (call_fct_extended_error, (void *) &cfei);
130: + };
131: + virtual ~call_fct_undo () {
132: + extended_error_state::pop ();
133: + };
134: + };
135: +
136: +
137: Ptype expr::call_fct(Ptable tbl)
138: + {
139: + call_fct_undo Undo;
140: +
141: + return call_fct0(tbl, (void *)&Undo.cfei);
142: + }
143: +
144: +
145: + Ptype expr::call_fct0(Ptable tbl, void * eei)
146: /*
147: check "this" call:
148: e1(e2)
149: ***************
150: *** 935,940 ****
151: --- 1001,1008 ----
152: // found without use of find_name()
153: int const_obj = 0;
154:
155: + call_fct_eei& cfei = *(call_fct_eei*)eei;
156: +
157: if (t1 == any_type) return any_type;
158:
159: switch (base) {
160: ***************
161: *** 1304,1316 ****
162: --- 1372,1393 ----
163: e = arg;
164: if (k == 0) goto rlab;
165:
166: + if(fct_name && fct_name->base == NAME)
167: + cfei.fname = fct_name;
168: +
169: for (nn=f->argtype, argno=1; e||nn; nn=nn->n_list, e=etail->e2, argno++) {
170: Pexpr a;
171:
172: + cfei.valid = 1;
173: + cfei.argx = argno;
174: + cfei.cur_formal = nn;
175: +
176: if (e) {
177: a = e->e1;
178: etail = e;
179:
180: + cfei.cur_actual = a;
181: +
182: if (nn) { /* type check */
183: Ptype t1 = nn->tp;
184: //error('d',"argtp %t etp %t a %k",t1,a->tp,a->base);
185: ***************
186: *** 1538,1546 ****
187: are handled correctly.
188: */
189: {
190: ! register Ptype it = init->tp;
191: ! Pptr px = p;
192: ! while (px->base == TYPE) px = Pptr(Pbase(px)->b_name->tp);
193: Ptype p1 = px->typ;
194: Pname c1 = p1->is_cl_obj();
195: //error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it);
196: --- 1615,1626 ----
197: are handled correctly.
198: */
199: {
200: ! /* p, the reference, has to to of a type reference-to-something.
201: ! consts of the form K & const are ignored for this purpose
202: ! while K const & aren't. this is ok, they don't mean anything.
203: ! Note that K & volatile and such are also ignored. --benson */
204: !
205: ! Pptr px = Pptr(Ptype(p)->underlying_type());
206: Ptype p1 = px->typ;
207: Pname c1 = p1->is_cl_obj();
208: //error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it);
209: ***************
210: *** 1552,1566 ****
211: && init->tp->base==FLOAT)
212: error('w',"initializing a float& with floatA is non-portable");
213:
214: ! rloop:
215: ! switch (it->base) {
216: ! case TYPE:
217: ! it = Pbase(it)->b_name->tp; goto rloop;
218: ! default:
219: ! { Ptype tt = it->addrof();
220: px->base = PTR; // allow &x for y& when y : public x
221: // but not &char for int&
222: int x = px->check(tt,COERCE);
223:
224: if (x == 0) { //CCC type is fine check for constness:
225: if (init->tp->tconst()
226: --- 1632,1642 ----
227: && init->tp->base==FLOAT)
228: error('w',"initializing a float& with floatA is non-portable");
229:
230: ! { Ptype tt = init->tp->underlying_type()->addrof();
231: px->base = PTR; // allow &x for y& when y : public x
232: // but not &char for int&
233: int x = px->check(tt,COERCE);
234: + if(const_problem) x = 0; /* we deal with const ourself */
235:
236: if (x == 0) { //CCC type is fine check for constness:
237: if (init->tp->tconst()
238: ***************
239: *** 1568,1574 ****
240: && fct_const==0) {
241: // not ``it''
242: if (init->base == ELIST) init = init->e1;
243: ! if (px->typ->tconst() == 0) error("R to constO");
244: px->base = RPTR;
245: // if we have a const lvalue we can still pass its address
246: extern ignore_const;
247: --- 1644,1656 ----
248: && fct_const==0) {
249: // not ``it''
250: if (init->base == ELIST) init = init->e1;
251: ! if (px->typ->tconst() == 0) {
252: ! if(init->tp->tconst (const_idx))
253: ! err::signal(malformed_expr,
254: ! "Non-constant reference to indexable object.");
255: ! err::signal(malformed_expr,
256: ! "Non-constant reference to constant object.");
257: ! }
258: px->base = RPTR;
259: // if we have a const lvalue we can still pass its address
260: extern ignore_const;
261: ***************
262: *** 1580,1585 ****
263: --- 1662,1673 ----
264: return ptr_init(px,init->address(),tbl);//return init->address();
265: }
266: ignore_const--;
267: + /* going to xxx implies that we are going
268: + to try to concoct a temp. Not permissible in
269: + the indexable case. */
270: + if(init->tp->tconst(const_idx))
271: + err::signal(malformed_expr,
272: + "Non-constant reference to indexable object.");
273: goto xxx;
274: }
275: px->base = RPTR;
276: ***************
277: *** 1593,1599 ****
278:
279: px->base = RPTR;
280: }
281: - }
282:
283: //error('d',"c1 %n",c1);
284: if (c1) { // assigning to a const X & is fine
285: --- 1681,1686 ----
286: ***************
287: *** 1604,1616 ****
288: init = x;
289: goto xxx;
290: }
291: ! while (p1->base==TYPE) p1 = Pbase(p1)->b_name->tp;
292: ! int bc = Pbase(p1)->b_const;
293: ! Pbase(p1)->b_const = 0;
294: ! refd = 1; /* disable itor */
295: Pexpr a = class_init(0,p1,init,tbl);
296: ! Pbase(p1)->b_const = bc;
297: ! refd = 0;
298: if (a==init && init->tp!=any_type) goto xxx;
299: //error('d',"ri a %d %k",a->base,a->base);
300: switch (a->base) {
301: --- 1691,1716 ----
302: init = x;
303: goto xxx;
304: }
305: ! /* This stretch of code is pretty surprising.
306: ! what about consts on typedefs on p1?
307: ! This is trying to turn const off for long enough to run class_init
308: ! and then turn it on again. If p1 is a class type, which seems
309: ! to be indicated by c1, then the typedefs can "only" carry const
310: ! and volatile. Since volatile isn't here yet, this is harmless. --benson */
311: !
312: ! if(Pclass(c1->tp)->c_abstract)
313: ! err::signal(malformed_expr,
314: ! "A temporary is needed for a parameter, but the argument type is abstract class %s.",
315: ! err::type_string(c1->tp));
316: !
317: !
318: ! Ptype p1u = p1->underlying_type ();
319: ! int bc = Pbase(p1u)->b_const;
320: ! Pbase(p1u)->b_const = 0;
321: ! refd ++; /* disable itor */
322: Pexpr a = class_init(0,p1,init,tbl);
323: ! Pbase(p1u)->b_const = bc;
324: ! refd --;
325: if (a==init && init->tp!=any_type) goto xxx;
326: //error('d',"ri a %d %k",a->base,a->base);
327: switch (a->base) {
328: ***************
329: *** 1628,1637 ****
330: // return ptr_init(px,a->address(),tbl);//a->address();
331: }
332:
333: ! //error('d',"p1 %t it %t",p1,it);
334: ! if (p1->check(it,0)) {
335:
336: ! if (p1->check(it,ASSIGN) == 0) {
337: // if (p1->is_ptr()) // check for base* = derived*
338: // goto xxx;
339:
340: --- 1728,1743 ----
341: // return ptr_init(px,a->address(),tbl);//a->address();
342: }
343:
344: ! //error('d',"p1 %t it %t",p1,init->tp);
345:
346: ! /* NOTE: in this region, several uses of "it" were converted to uses
347: ! if init->tp rather than to init->tp->underlying_type(). Since
348: ! these are type checks, it seems nonsensical to ignore signed/unsigned
349: ! and related items. --benson */
350: !
351: ! if (p1->check(init->tp,0)) {
352: !
353: ! if (p1->check(init->tp,ASSIGN) == 0) {
354: // if (p1->is_ptr()) // check for base* = derived*
355: // goto xxx;
356:
357: ***************
358: *** 1649,1655 ****
359: goto def;
360: }
361:
362: ! error("badIrT:%t (%tX)",it,p);
363: if (init->base != NAME) init->tp = any_type;
364: return init;
365: }
366: --- 1755,1761 ----
367: goto def;
368: }
369:
370: ! error("badIrT:%t (%tX)",init->tp,p);
371: if (init->base != NAME) init->tp = any_type;
372: return init;
373: }
374: ***************
375: *** 1668,1674 ****
376: case DEREF:
377: case REF:
378: case DOT: // init => &init
379: ! if (it->tconst() && vec_const==0 && fct_const==0) goto def;
380: init->lval(ADDROF);
381: if (vec_const) return init;
382: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct
383: --- 1774,1780 ----
384: case DEREF:
385: case REF:
386: case DOT: // init => &init
387: ! if (init->tp->tconst() && vec_const==0 && fct_const==0) goto def;
388: init->lval(ADDROF);
389: if (vec_const) return init;
390: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct
391: ***************
392: *** 1681,1686 ****
393: --- 1787,1799 ----
394: {
395: //error('d',"def: init->tp %t p1 %t",init->tp,p1);
396: if (tbl == gtbl) error("Ir for staticR not an lvalue");
397: +
398: + Pname tcl = p1->is_cl_obj ();
399: + if(tcl && Pclass(tcl->tp)->c_abstract)
400: + err::signal(malformed_expr,
401: + "A temporary is needed for a parameter, but the argument type is abstract class %s.",
402: + err::type_string(tcl->tp));
403: +
404: Pname n = make_tmp('I',p1,tbl);
405: Pexpr a;
406: Pname ic = init->tp->is_cl_obj();
407: ***************
408: *** 1687,1705 ****
409:
410: if (p1->tconst()==0
411: && (init->tp->tconst() && vec_const==0 && fct_const==0)
412: ! && p1->check(it,ASSIGN)==0)
413: ! error('w',"constIr: temporary used toI reference");
414: !
415: switch (p1->base) {
416: case INT:
417: case CHAR:
418: case SHORT:
419: ! switch (it->base) {
420: case LONG:
421: case FLOAT:
422: case DOUBLE:
423: case LDOUBLE:
424: ! error('w',"%t assigned to %t inRIr",it,p1);
425: }
426: }
427:
428: --- 1800,1821 ----
429:
430: if (p1->tconst()==0
431: && (init->tp->tconst() && vec_const==0 && fct_const==0)
432: ! && p1->check(init->tp,ASSIGN)==0) {
433: ! if(init->tp->tconst(const_idx))
434: ! err::signal(malformed_expr,
435: ! "Temporary copy of indexable item would be needed to initialize non-constant reference.");
436: ! error('w',"constIr: temporary used toI reference");
437: ! }
438: switch (p1->base) {
439: case INT:
440: case CHAR:
441: case SHORT:
442: ! switch (init->tp->underlying_type()->base) {
443: case LONG:
444: case FLOAT:
445: case DOUBLE:
446: case LDOUBLE:
447: ! error('w',"%t assigned to %t inRIr",init->tp,p1);
448: }
449: }
450:
451: ***************
452: *** 2249,2258 ****
453: return c;
454: }
455: }
456: ! static char rcsinfo[] = "$Header: /usr3/lang/benson/work/stripped_cfront/O/RCS/expr3.c,v 1.8 89/10/16 08:15:27 benson Exp $";
457:
458:
459: /* $Log: expr3.c,v $
460: * Revision 1.8 89/10/16 08:15:27 benson
461: * distinguish indedxable from const in argument passing.
462: *
463: --- 2365,2379 ----
464: return c;
465: }
466: }
467: ! static char rcsinfo[] = "$Header: /usr3/lang/benson/work/stripped_cfront/O/RCS/expr3.c,v 1.9 89/10/20 14:30:34 benson Exp $";
468:
469:
470: /* $Log: expr3.c,v $
471: + * Revision 1.9 89/10/20 14:30:34 benson
472: + * fixes to typ handling in function calls to eliminate some strange
473: + * temps. Also catch indexable explicitly here. Also make error context
474: + * for any arg-related error message.
475: + *
476: * Revision 1.8 89/10/16 08:15:27 benson
477: * distinguish indedxable from const in argument passing.
478: *
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.