"Fossies" - the Fresh Open Source Software Archive 
Member "ncc-2.8/usage.C" (11 Oct 2008, 22213 Bytes) of package /linux/privat/old/ncc-2.8.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*****************************************************************************
2 $ C-flow and data usage analysis.
3 $
4 $ Stripped-down version of ccexpr. expressions are compiled but
5 $ without producing bytecode assembly. just inform about
6 $ function calls, use of global variables and use of members
7 $ of structures
8 *****************************************************************************/
9 #include <stdio.h>
10 #include <assert.h>
11
12 #include "global.h"
13 #include "inttree.h"
14
15 bool infuncs = false;
16
17 static intTree printed;
18 static intTree printed_function;
19
20 //***********************************************************
21 // Output Formats & Text
22 //***********************************************************
23
24 static char *txt_func = "\nD: %s()\n";
25 static char *txt_fcall = "F: %s()\n";
26 static char *txt_virt = "F: (*virtual)()\n";
27 static char *txt_error = "F: NCC:syntax_error()\n";
28 static char *txt_gvar_r = "g: %s\n";
29 static char *txt_evar_r = "g: %s\n";
30 static char *txt_gvar_ra = "g: %s[]\n";
31 static char *txt_evar_ra = "g: %s[]\n";
32 static char *txt_gvar = "G: %s\n";
33 static char *txt_gvar_a = "G: %s[]\n";
34 static char *txt_evar = "G: %s\n";
35 static char *txt_evar_a = "G: %s[]\n";
36 static char *txt_memb_r = "s: %s.%s\n";
37 static char *txt_memb = "S: %s.%s\n";
38 static char *txt_memb_ra = "s: %s.%s[]\n";
39 static char *txt_memb_a = "S: %s.%s[]\n";
40 static char *txt_fpcall = "F: *%s()\n";
41 static char *txt_fcallback = "F: *%s.%s()\n";
42 static char *farg_named_call = "F: %s/%s()\n";
43 static char *farg_call_redirect = "\nD: %s/%s()\nF: *%s()__farg%i()\n";
44 static char *txt_argval = "R: *%s()__farg%i() %s()\n";
45 static char *txt_argvalf = "R: *%s()__farg%i() *%s()\n";
46 static char *txt_argvalfl = "R: *%s()__farg%i() %s/%s()\n";
47 static char *txt_argvalargval = "R: *%s()__farg%i() *%s()__farg%i()\n";
48 static char *txt_membargval = "R: *%s()__farg%i() *%s.%s()\n";
49
50 //********************************************
51
52 char *structname (Symbol s)
53 {
54 return s == -1 ? (char*) "{anonymous}" : C_Syms [SYMBOLID (s)];
55 }
56
57 void report (Symbol s, int frame, bool wrt, bool arr)
58 {
59 if (INGLOBAL || !infuncs) return;
60 if (!multiple) {
61 if (printed.intFind ((wrt ? 1000000 : 0) + (arr ? 2000000 : 0) +
62 frame * 100000 + s))
63 return;
64 else new intNode (&printed);
65 }
66
67 if (frame == -1 ) PRINTF (wrt ? (arr ? txt_evar_a : txt_evar) :
68 arr ? txt_evar_ra : txt_evar_r, C_Syms [SYMBOLID (s)]);
69 else if (frame == 0 ) PRINTF (wrt ? (arr ? txt_gvar_a : txt_gvar) :
70 arr ? txt_gvar_ra : txt_gvar_r, C_Syms [SYMBOLID (s)]);
71 else PRINTF (wrt ? (arr ? txt_memb_a : txt_memb) : arr ? txt_memb_ra : txt_memb_r,
72 structname (struct_by_name (frame)), C_Syms [SYMBOLID (s)]);
73 if (arr) report (s, frame, false, false);
74 }
75
76 static Symbol current_function;
77
78 void newfunction (Symbol s)
79 {
80 current_function = s;
81 PRINTF (txt_func, C_Syms [SYMBOLID (s)]);
82 if (printed.root) {
83 delete printed.root;
84 printed.root = NULL;
85 }
86 if (printed_function.root) {
87 delete printed_function.root;
88 printed_function.root = NULL;
89 }
90 }
91
92 static bool local_object (Symbol s)
93 {
94 lookup_object L (s);
95 return L.FRAME > 0;
96 }
97
98 void report_call (Symbol s, bool pointer)
99 {
100 Symbol func = pointer && local_object (s) ? current_function : 0;
101 if (!multiple)
102 if (printed_function.intFind (s + func)) return;
103 else new intNode (&printed_function);
104 if (func)
105 PRINTF (farg_named_call, C_Syms [SYMBOLID (func)], C_Syms [SYMBOLID (s)]);
106 else
107 PRINTF (pointer ? txt_fpcall : txt_fcall, C_Syms [SYMBOLID (s)]);
108 }
109
110 void report_callback (Symbol rec, Symbol s)
111 {
112 PRINTF (txt_fcallback, structname (rec), C_Syms [SYMBOLID (s)]);
113 }
114
115 struct argnameassign { Symbol s1, s2; int argi; };
116 static earray<argnameassign> arg_names;
117
118 static void stor_named_conv (Symbol f, Symbol a, int n)
119 {
120 int i = arg_names.alloc ();
121 arg_names.x [i].s1 = SYMBOLID (f);
122 arg_names.x [i].s2 = SYMBOLID (a);
123 arg_names.x [i].argi = n;
124 }
125
126 void report_named_convert ()
127 {
128 int i;
129 if (arg_names.nr) PRINTF ("\n");
130 for (i = 0; i < arg_names.nr; i++)
131 PRINTF (farg_call_redirect, C_Syms [arg_names.x [i].s1], C_Syms [arg_names.x [i].s2],
132 C_Syms [arg_names.x [i].s1], arg_names.x [i].argi);
133 }
134
135 void report_fargcall (int a, Symbol s)
136 {
137 stor_named_conv (current_function, s, a);
138 PRINTF (farg_named_call, C_Syms [SYMBOLID (current_function)], C_Syms [SYMBOLID (s)]);
139 }
140
141 struct fptrassign { Symbol s1, s2, m1, m2, fn, fn1; bool sptr, a1, a2; };
142 static earray<fptrassign> fptr_assignments;
143
144 // some help with the arguments
145 // 's1' and 's2' are the names of the functions assigned.
146 // For example 'funcptr=foo', s1=funcptr and s2=foo
147 // 'm1' and 'm2' are useful for the case one of the two is a member
148 // For example 'obj->funcptr=foo' or 'obj->funcptr=x.f'
149 // if 'fn' is present then the second call is converted to 'fn/s2()'
150 // if 'fn1' is present then the first call is of 'f1/s1()' form
151 // This is all too hairy but this function is the result of hacking
152 // and extending ncc itself.
153 //
154 void functionptr (Symbol s1, Symbol s2, bool pointer, Symbol m1, Symbol m2, Symbol fn, Symbol fn1, bool a1, bool a2)
155 {
156 int i;
157 for (i = 0; i < fptr_assignments.nr; i++) {
158 fptrassign fp = fptr_assignments.x [i];
159 if (fp.s1 == s1 && fp.s2 == s2
160 && fp.fn == fn && fp.fn1 == fn1
161 && fp.a1 == a1 && fp.a2 == a2
162 && fp.m1 == m1 && fp.m2 == m2) return;
163 }
164
165 i = fptr_assignments.alloc ();
166 fptr_assignments.x [i].s1 = s1;
167 fptr_assignments.x [i].s2 = s2;
168 fptr_assignments.x [i].m1 = m1;
169 fptr_assignments.x [i].m2 = m2;
170 fptr_assignments.x [i].sptr = pointer;
171 fptr_assignments.x [i].fn = fn;
172 fptr_assignments.x [i].a1 = a1;
173 fptr_assignments.x [i].a2 = a2;
174 fptr_assignments.x [i].fn1 = fn1;
175 }
176
177 void report_fptrs ()
178 {
179 int i;
180 for (i = 0; i < fptr_assignments.nr; i++) {
181 fptrassign fp = fptr_assignments.x [i];
182
183 PRINTF ("\nD: ");
184 if (fp.m1 == -1 && fp.fn1 != -1)
185 PRINTF ("%s/", C_Syms [SYMBOLID (fp.fn1)]);
186 else if (fp.m1 != -1)
187 PRINTF ("*%s.", structname (fp.s1));
188 else PRINTF ("*");
189 PRINTF ("%s", C_Syms [fp.m1 == -1 ? SYMBOLID (fp.s1) : SYMBOLID (fp.m1)]);
190 if (fp.a1) PRINTF ("[]");
191 PRINTF ("()\n");
192
193 PRINTF ("F: ");
194 if (fp.m2 == -1 && fp.fn != -1)
195 PRINTF ("%s/", C_Syms [SYMBOLID (fp.fn)]);
196 else if (fp.m2 == -1 && fp.fn == -1 && fp.sptr)
197 PRINTF ("*");
198 else if (fp.m2 != -1)
199 PRINTF ("*%s.", structname (fp.s2));
200 PRINTF ("%s", C_Syms [fp.m2 == -1 ? SYMBOLID (fp.s2) : SYMBOLID (fp.m2)]);
201 if (fp.a2) PRINTF ("[]");
202 PRINTF ("()\n");
203 }
204 }
205
206 void report_virtual ()
207 {
208 PRINTF (txt_virt);
209 }
210
211 void report_error ()
212 {
213 PRINTF (txt_error);
214 }
215
216 struct fargsave { Symbol f, f2, s, lf; int ia, ia2; bool ptr; };
217 static earray<fargsave> farg_saves;
218
219 void report_fargval (Symbol f, int ia, Symbol f2, int ia2, bool ptr = false)
220 {
221 int i = farg_saves.alloc ();
222 farg_saves.x [i].f = f;
223 farg_saves.x [i].f2 = f2;
224 farg_saves.x [i].ia = ia;
225 farg_saves.x [i].ia2 = ia2;
226 farg_saves.x [i].ptr = ptr;
227 farg_saves.x [i].lf = farg_saves.x [i].s = -1;
228 }
229
230 void report_fargval_memb (Symbol f, int ia, Symbol s, Symbol m)
231 {
232 int i = farg_saves.alloc ();
233 farg_saves.x [i].f = f;
234 farg_saves.x [i].f2 = m;
235 farg_saves.x [i].ia = ia;
236 farg_saves.x [i].s = s;
237 farg_saves.x [i].lf = -1;
238 }
239
240 void report_fargval_locf (Symbol f, int ia, Symbol f2, Symbol l)
241 {
242 int i = farg_saves.alloc ();
243 farg_saves.x [i].f = f;
244 farg_saves.x [i].f2 = f2;
245 farg_saves.x [i].ia = ia;
246 farg_saves.x [i].lf = l;
247 farg_saves.x [i].s = -1;
248 }
249
250 void report_argument_calls ()
251 {
252 int i;
253 if (farg_saves.nr) PRINTF ("\n");
254 for (i = 0; i < farg_saves.nr; i++)
255 if (farg_saves.x [i].s != -1)
256 PRINTF (txt_membargval, C_Syms [SYMBOLID (farg_saves.x [i].f)],
257 farg_saves.x [i].ia, C_Syms [SYMBOLID (farg_saves.x [i].s)],
258 C_Syms [SYMBOLID (farg_saves.x [i].f2)]);
259 else if (farg_saves.x [i].lf != -1)
260 PRINTF (txt_argvalfl, C_Syms [SYMBOLID (farg_saves.x [i].f)],
261 farg_saves.x [i].ia, C_Syms [SYMBOLID (farg_saves.x [i].lf)],
262 C_Syms [SYMBOLID (farg_saves.x [i].f2)]);
263 else if (farg_saves.x [i].ia2 == -1)
264 PRINTF (farg_saves.x [i].ptr ? txt_argvalf : txt_argval,
265 C_Syms [SYMBOLID (farg_saves.x [i].f)],
266 farg_saves.x [i].ia, C_Syms [SYMBOLID (farg_saves.x [i].f2)]);
267 else
268 PRINTF (txt_argvalargval, C_Syms [SYMBOLID (farg_saves.x [i].f)],
269 farg_saves.x [i].ia, C_Syms [SYMBOLID (farg_saves.x [i].f2)],
270 farg_saves.x [i].ia2);
271 }
272
273 class ccsub_small
274 {
275 inline void fconv ();
276 inline void iconv ();
277 inline void settype (int);
278 inline void lvaluate ();
279 inline void copytype (ccsub_small&);
280 inline void degrade (ccsub_small&);
281 inline void arithmetic_convert (ccsub_small&, ccsub_small&);
282 inline bool arithmetic ();
283 inline bool voidp ();
284 inline bool structure ();
285 inline void assign_convert (ccsub_small&);
286 bool op1return;
287 static ccsub_small op1;
288 inline void cc_binwconv (ccsub_small&, ccsub_small&);
289 inline void cc_addptr (ccsub_small&, ccsub_small&);
290 bool lv, modify, array;
291 void cc_fcall (exprID);
292 void cc_prepostfix (exprID);
293 inline void cc_terminal (exprID);
294 inline void cc_dot (exprID);
295 inline void cc_array (exprID);
296 inline void cc_star (exprID);
297 inline void cc_addrof (exprID);
298 inline void cc_ecast (exprID);
299 inline void cc_usign (exprID);
300 inline void cc_nbool (exprID);
301 inline void cc_compl (exprID);
302 inline void cc_add (exprID, bool = false);
303 void cc_sub (exprID, bool = false);
304 void cc_muldiv (exprID, bool = false);
305 void cc_bintg (exprID, bool = false);
306 inline void cc_cmp (exprID);
307 void cc_bool (exprID);
308 void cc_conditional (exprID, exprID = -2);
309 void cc_assign (exprID);
310 void cc_oassign (exprID);
311 inline void cc_compound (exprID);
312 public:
313 inline ccsub_small (exprID, bool = false, bool = false);
314 ccsub_small () {}
315 ccsub_small (typeID, char*);
316
317 int base, spec [MSPEC];
318 };
319
320 ccsub_small ccsub_small::op1;
321
322 void ccsub_small::cc_terminal (exprID ei)
323 {
324 subexpr e = ee [ei];
325 lookup_object ll (e.voici.symbol);
326 if (ll.enumconst) {
327 settype (S_INT);
328 return;
329 }
330 base = ll.base;
331 intcpy (spec, ll.spec);
332 if (ll.FRAME <= 0)
333 report (e.voici.symbol, ll.FRAME, modify, array);
334 lvaluate ();
335 }
336
337 void ccsub_small::cc_addrof (exprID ei)
338 {
339 ccsub_small o (ee [ei].voici.e);
340
341 base = o.base;
342 if (o.lv || o.structure ()) {
343 spec [0] = '*';
344 intcpy (&spec [1], o.spec);
345 } else if (o.spec [0] != -1)
346 intcpy (spec, o.spec);
347 else half_error ("&address_of not addressable");
348 }
349
350 void ccsub_small::cc_star (exprID e)
351 {
352 ccsub_small o (ee [e].voici.e);
353 degrade (o);
354 lvaluate ();
355 }
356
357 void ccsub_small::cc_array (exprID ei)
358 {
359 ccsub_small o1 (ee [ei].voici.e, modify, true), o2 (ee [ei].e);
360 cc_addptr (o1, o2);
361 degrade (*this);
362 lvaluate ();
363 }
364
365 void ccsub_small::cc_dot (exprID ei)
366 {
367 subexpr e = ee [ei];
368 ccsub_small o (e.voici.e, modify);
369 lookup_member lm (e.voila.member, o.base);
370 base = lm.base;
371 intcpy (spec, lm.spec);
372 report (e.voila.member, o.base, modify, array);
373 lvaluate ();
374 }
375
376 void ccsub_small::cc_ecast (exprID ei)
377 {
378 subexpr e = ee [ei];
379 ccsub_small o (e.voici.e), pseudo (e.voila.cast, "");
380 o.assign_convert (pseudo);
381 copytype (o);
382 *this = o;
383 }
384
385 void ccsub_small::cc_usign (exprID ei)
386 {
387 subexpr e = ee [ei];
388 ccsub_small o (e.voici.e);
389 copytype (o);
390 }
391
392 void ccsub_small::cc_nbool (exprID ei)
393 {
394 ccsub_small o (ee [ei].voici.e);
395 (void) o;
396 settype (S_INT);
397 }
398
399 void ccsub_small::cc_compl (exprID ei)
400 {
401 ccsub_small o (ee [ei].voici.e);
402 (void) o;
403 settype (S_INT);
404 }
405
406 void ccsub_small::cc_bintg (exprID ei, bool m1)
407 {
408 subexpr e = ee [ei];
409 ccsub_small o1 (e.voici.e, m1), o2 (e.e);
410 (void) o2;
411 if (op1return) op1 = o1;
412 settype (S_INT);
413 }
414
415 void ccsub_small::cc_muldiv (exprID ei, bool m1)
416 {
417 subexpr e = ee [ei];
418 ccsub_small o1 (e.voici.e, m1), o2 (e.e);
419 if (op1return) op1 = o1;
420 cc_binwconv (o1, o2);
421 }
422
423 void ccsub_small::cc_prepostfix (exprID ei)
424 {
425 subexpr e = ee [ei];
426 ccsub_small o (e.voici.e, true);
427 copytype (o);
428 }
429
430 void ccsub_small::cc_add (exprID ei, bool m1)
431 {
432 subexpr e = ee [ei];
433 ccsub_small o1 (e.voici.e, m1), o2 (e.e);
434
435 if (op1return) op1 = o1;
436 if (o1.arithmetic () && o2.arithmetic ())
437 cc_binwconv (o1, o2);
438 else cc_addptr (o1, o2);
439 }
440
441 void ccsub_small::cc_sub (exprID ei, bool m1)
442 {
443 subexpr e = ee [ei];
444 ccsub_small o1 (e.voici.e, m1), o2 (e.e);
445
446 if (op1return) op1 = o1;
447
448 if (o1.arithmetic () && o2.arithmetic ()) {
449 cc_binwconv (o1, o2);
450 return;
451 }
452
453 if (!o1.arithmetic () && !o2.arithmetic ()) settype (S_INT);
454 else copytype (o1);
455 }
456
457 void ccsub_small::cc_cmp (exprID ei)
458 {
459 subexpr e = ee [ei];
460 ccsub_small o1 (e.voici.e), o2 (e.e);
461
462 if (o1.arithmetic () && o1.arithmetic ())
463 arithmetic_convert (o1, o2);
464 settype (S_INT);
465 }
466
467 void ccsub_small::cc_bool (exprID ei)
468 {
469 subexpr e = ee [ei];
470 ccsub_small o1 (e.voici.e);
471 ccsub_small o2 (e.e);
472 (void) o1;
473 (void) o2;
474 settype (S_INT);
475 }
476
477 void ccsub_small::cc_conditional (exprID ei, exprID args)
478 {
479 subexpr e = ee [ei];
480 if (args != -2) {
481 // we have the:
482 // (i ? a : b) ()
483 // case. Convert it to:
484 // (i ? a () : b ())
485 ee [NeTop] = ee [e.e];
486 ee [e.e].action = FCALL;
487 ee [e.e].voici.e = NeTop++;
488 ee [e.e].e = args;
489 ee [NeTop] = ee [e.voila.eelse];
490 ee [e.voila.eelse].action = FCALL;
491 ee [e.voila.eelse].voici.e = NeTop++;
492 ee [e.voila.eelse].e = args;
493 }
494 ccsub_small o (e.voici.e);
495 ccsub_small o1 (e.e);
496 ccsub_small o2 (e.voila.eelse);
497 ccsub_small *po = e.e==-1 ? &o : &o1;
498 (void) o1;
499 (void) o2;
500 (void) o;
501 if (po->arithmetic () || po->voidp ()) copytype (o2);
502 else copytype (*po);
503 }
504
505 static void callbacks (exprID e1, exprID e2)
506 {
507 Symbol s1, s2, m1 = -1, m2 = -1, fn = -1, fn1 = -1;
508 bool ptrs = false;
509 int a1 = 0, a2 = 0;
510
511 again1: if (ee [e1].action == SYMBOL) {
512 --a1;
513 s1 = ee [e1].voici.symbol;
514 if (local_object (s1))
515 fn1 = current_function;
516 } else if (ee [e1].action == MEMB) {
517 ccsub_small os (ee [e1].voici.e);
518 --a1;
519 s1 = struct_by_name (os.base);
520 m1 = ee [e1].voila.member;
521 } else if (ee [e1].action == ARRAY || ee [e1].action == PTRIND) {
522 e1 = ee [e1].voici.e;
523 a1 = 2;
524 goto again1;
525 } else return;
526
527 bool casted = false;
528 again: if (ee [e2].action == SYMBOL) {
529 --a2;
530 s2 = ee [e2].voici.symbol;
531 if ((ptrs = !have_function (s2))) {
532 lookup_function lf (s2, false);
533 if (!lf.found) return;
534 if (lf.ARGFUNC) {
535 fn = current_function;
536 // fn = s2;
537 // s2 = current_function;
538 stor_named_conv (s2, fn, lf.displacement);
539 } else if (lf.fptr && lf.FRAME > 0) {
540 // fn = s2;
541 // s2 = current_function;
542 fn = current_function;
543 }
544 }
545 } else if (ee [e2].action == MEMB) {
546 --a2;
547 ccsub_small os (ee [e2].voici.e);
548 s2 = struct_by_name (os.base);
549 m2 = ee [e2].voila.member;
550 } else if (casted = ee [e2].action == CAST) {
551 e2 = ee [e2].voici.e;
552 goto again;
553 } else if (ee [e2].action == ARRAY || ee [e2].action == PTRIND) {
554 e2 = ee [e2].voici.e;
555 a2 = 2;
556 goto again;
557 } else if (ee [e2].action == COND) {
558 callbacks (e1, ee [e2].e == -1 ? ee [e2].voici.e : ee [e2].e);
559 callbacks (e1, ee [e2].voila.eelse);
560 return;
561 } else return;
562
563 functionptr (s1, s2, ptrs, m1, m2, fn, fn1, a1 == 1, a2 == 1);
564 }
565
566 void ccsub_small::cc_assign (exprID ei)
567 {
568 subexpr e = ee [ei];
569 ccsub_small o1 (e.voici.e, true), o2 (e.e);
570
571 if (o1.spec[0] == '*' && o1.spec [1] == '(')
572 callbacks (e.voici.e, e.e);
573
574 (void) o2.lv;
575 copytype (o1);
576 }
577
578 void ccsub_small::cc_oassign (exprID ei)
579 {
580 op1return = true;
581 switch (ee [ei].action) {
582 case ASSIGNA: cc_add (ei, true); break;
583 case ASSIGNS: cc_sub (ei, true); break;
584 case ASSIGNM:
585 case ASSIGND: cc_muldiv (ei, true); break;
586 case ASSIGNBA: case ASSIGNBX: case ASSIGNBO:
587 case ASSIGNRS: case ASSIGNLS:
588 case ASSIGNR: cc_bintg (ei, true); break;
589 }
590 copytype (op1);
591 }
592
593 static void fargs (exprID ei, Symbol fs, int i)
594 {
595 again: if (ee [ei].action == SYMBOL) {
596 Symbol t = ee [ei].voici.symbol;
597 if (have_function (t))
598 report_fargval (fs, i, t, -1);
599 else {
600 lookup_function lf (t, false);
601 if (!lf.found) return;
602 if (lf.ARGFUNC)
603 report_fargval (fs, i, current_function, lf.displacement);
604 else if (!local_object (t))
605 report_fargval (fs, i, t, -1, true);
606 else
607 report_fargval_locf (fs, i, t, current_function);
608 }
609 } else if (ee [ei].action == MEMB) {
610 ccsub_small oo (ee [ei].voici.e);
611 report_fargval_memb (fs, i, struct_by_name (oo.base),
612 ee [ei].voila.member);
613 } else if (ee [ei].action == CAST) {
614 ei = ee [ei].voici.e;
615 goto again;
616 }
617 }
618
619 void ccsub_small::cc_fcall (exprID ei)
620 {
621 int i = 2;
622 subexpr e = ee [ei];
623 subexpr fe = ee [e.voici.e];
624 Symbol fs = -1;
625
626 if (fe.action == SYMBOL) {
627 lookup_function lf (fe.voici.symbol);
628 fs = fe.voici.symbol;
629 if (!lf.ARGFUNC)
630 report_call (fe.voici.symbol, lf.fptr);
631 else
632 report_fargcall (lf.displacement, fe.voici.symbol);
633 base = lf.base;
634 intcpy (spec, lf.spec + 2);
635 } else if (fe.action == COND) {
636 cc_conditional (e.voici.e, e.e);
637 return;
638 } else {
639 ccsub_small fn (e.voici.e);
640
641 if (fn.spec [0] != '(') {
642 if (fn.spec [0] == '*' && fn.spec [1] == '(')
643 i = 3;
644 else half_error ("not a function");
645 }
646 base = fn.base;
647 intcpy (spec, fn.spec + i);
648
649 if (fe.action == MEMB) {
650 ccsub_small os (fe.voici.e);
651 report_callback (struct_by_name (os.base), fe.voila.member);
652 } else if (fe.action == PTRIND) {
653 if (ee [fe.voici.e].action == MEMB) {
654 subexpr effi = ee [fe.voici.e];
655 ccsub_small os (effi.voici.e);
656 report_callback (struct_by_name (os.base), effi.voila.member);
657 } else if (ee [fe.voici.e].action == SYMBOL) {
658 lookup_function lf (ee [fe.voici.e].voici.symbol, false);
659 if (!lf.ARGFUNC)
660 report_call (fs = ee [fe.voici.e].voici.symbol, true);
661 else
662 report_fargcall (lf.displacement, ee [fe.voici.e].voici.symbol);
663 }
664 } else report_virtual ();
665 }
666
667 if ((ei = e.e) != -1) {
668 int i;
669 bool fsok = fs != -1 && fs != current_function;
670
671 for (i = 0; ee [ei].action == ARGCOMMA; ei = ee [ei].e, i++) {
672 exprID eii = ee [ei].voici.e;
673 ccsub_small o (eii);
674 o.lv = o.lv;
675 if (fsok && o.spec [0] == '*' && o.spec [1] == '(')
676 fargs (eii, fs, i);
677 }
678 ccsub_small o (ei);
679 o.lv = o.lv;
680 if (fsok && o.spec [0] == '*' && o.spec [1] == '(')
681 fargs (ei, fs, i);
682 }
683 }
684
685 void ccsub_small::cc_compound (exprID ei)
686 {
687 base = base_of (ee [ei].voila.result_type);
688 intcpy (spec, spec_of (ee [ei].voila.result_type));
689 }
690
691 ////////////////////////////////////////////////////////////////////////////
692
693 void ccsub_small::cc_binwconv (ccsub_small &o1, ccsub_small &o2)
694 {
695 arithmetic_convert (o1, o2);
696 settype (o1.base);
697 }
698
699 void ccsub_small::cc_addptr (ccsub_small &o1, ccsub_small &o2)
700 {
701 bool b2 = o2.arithmetic ();
702 if (b2) {
703 o2.lv = false;
704 copytype (o1);
705 } else {
706 o1.lv = false;
707 copytype (o2);
708 }
709 }
710
711 void ccsub_small::copytype (ccsub_small &o)
712 {
713 base = o.base;
714 intcpy (spec, o.spec);
715 }
716
717 void ccsub_small::degrade (ccsub_small &o)
718 {
719 base = o.base;
720 if (o.spec [0] == -1) half_error ("Not a pointer");
721 intcpy (spec, o.spec + (o.spec [0] == '(' ? 0 : o.spec [0] == '*' ? 1 : 2));
722 }
723
724 bool ccsub_small::structure ()
725 {
726 return spec [0] == -1 && base >= 0;
727 }
728
729 bool ccsub_small::arithmetic ()
730 {
731 return spec [0] == -1 && base < VOID || spec [0] == ':';
732 }
733
734 bool ccsub_small::voidp ()
735 {
736 return spec [0] == '*' && base == VOID;
737 }
738
739 void ccsub_small::lvaluate ()
740 {
741 lv = !(spec [0] =='[' || spec [0] ==-1 && base >=0 || spec [0] =='(');
742 }
743
744 void ccsub_small::settype (int b)
745 {
746 base = b;
747 spec [0] = -1;
748 }
749
750 void ccsub_small::assign_convert (ccsub_small &o)
751 {
752 if (o.arithmetic ())
753 if (o.base != FLOAT) iconv ();
754 else fconv ();
755 base = o.base;
756 intcpy (spec, o.spec);
757 }
758
759 void ccsub_small::arithmetic_convert (ccsub_small &o1, ccsub_small &o2)
760 {
761 if (o1.base == FLOAT || o2.base == FLOAT) {
762 if (o1.base != o2.base)
763 if (o1.base == FLOAT) o2.fconv ();
764 else o1.fconv ();
765 }
766 }
767
768 void ccsub_small::fconv ()
769 {
770 settype (FLOAT);
771 }
772
773 void ccsub_small::iconv ()
774 {
775 settype (S_INT);
776 }
777
778 //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
779
780 ccsub_small::ccsub_small (exprID ei, bool mod, bool arr)
781 {
782 modify = mod;
783 array = arr;
784 if (ei == -1) return;
785 advance:
786 subexpr e = ee [ei];
787
788 lv = false;
789 op1return = false;
790 switch (e.action) {
791 case VALUE:
792 case UVALUE: settype (S_INT); break;
793 case FVALUE: settype (FLOAT); break;
794 case SVALUE: base = S_CHAR; spec [0] = '*'; spec [1] = -1;
795 break;
796 case AVALUE: base = VOID; spec [0] = '*'; spec [1] = -1;
797 break;
798 case SYMBOL: cc_terminal (ei); break;
799 case FCALL: cc_fcall (ei); break;
800 case MEMB: cc_dot (ei); break;
801 case ARRAY: cc_array (ei); break;
802 case ADDROF: cc_addrof (ei); break;
803 case PTRIND: cc_star (ei); break;
804 case MMPOST: case PPPOST:
805 case PPPRE:
806 case MMPRE: cc_prepostfix (ei); break;
807 case CAST: cc_ecast (ei); break;
808 case LNEG: cc_nbool (ei); break;
809 case OCPL: cc_compl (ei); break;
810 case UPLUS:
811 case UMINUS: cc_usign (ei); break;
812 case SIZEOF: settype (S_INT); break;
813 case MUL:
814 case DIV: cc_muldiv (ei); break;
815 case ADD: cc_add (ei); break;
816 case SUB: cc_sub (ei); break;
817 case SHR: case SHL: case BOR: case BAND: case BXOR:
818 case REM: cc_bintg (ei); break;
819 case IAND:
820 case IOR: cc_bool (ei); break;
821 case BNEQ: case CGR: case CGRE: case CLE: case CLEE:
822 case BEQ: cc_cmp (ei); break;
823 case COND: cc_conditional (ei); break;
824 case COMPOUND_RESULT: cc_compound (ei); break;
825 case COMMA: {
826 ccsub_small o (e.voici.e);
827 ei = e.e;
828 (void) o;
829 goto advance;
830 }
831 default:
832 if (e.action == '=') cc_assign (ei);
833 else cc_oassign (ei);
834 }
835 }
836
837
838 ccsub_small::ccsub_small (typeID t, char*)
839 {
840 base = base_of (t);
841 intcpy (spec, spec_of (t));
842 }
843
844 //
845 //
846 //
847 //
848
849 class ncci_usage : public ncci
850 {
851 public:
852 void cc_expression ();
853 void new_function (Symbol);
854 void inline_assembly (NormPtr, int);
855 void finir ();
856 };
857
858 void ncci_usage::cc_expression ()
859 {
860 try {
861 if (CExpr.first != -1) {
862 ccsub_small CC (CExpr.first);
863 #ifdef GNU_VIOLATIONS
864 last_result_type.base = CC.base;
865 intcpy (last_result_type.spec, CC.spec);
866 #endif
867 }
868 } catch (EXPR_ERROR) { }
869 last_result++;
870 }
871
872 void ncci_usage::new_function (Symbol s)
873 {
874 newfunction (s);
875 }
876
877 void ncci_usage::inline_assembly (NormPtr p, int n)
878 {
879 // hoping that inline assembly won't use global variables,
880 // nor call functions, it is ignored (for now at least)
881 }
882
883 void ncci_usage::finir ()
884 {
885 report_fptrs ();
886 report_named_convert ();
887 report_argument_calls ();
888 }
889
890 void set_usage_report ()
891 {
892 ncc = new ncci_usage;
893 }