"Fossies" - the Fresh Open Source Software Archive 
Member "ncc-2.8/cdb.C" (11 Oct 2008, 36155 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
3 data collected from the parser
4
5 *****************************************************************************/
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <assert.h>
11
12 #include "global.h"
13 #include "dbstree.h"
14 #include "inttree.h"
15 #include "mem_pool.h"
16
17 /*****************************************************************************
18 #
19 # the most complex part in a C compiler is the data structures
20 # storing what is introduced from the declarations.
21 #
22 # the base to understanding how the program works, is understanding
23 # the way data is stored and retrieved from this cdb.
24 #
25 # what this file provides is described in global.h at
26 # `CDB interface'
27 #
28 # this is where all the money went...
29 *****************************************************************************/
30
31 /*****************************************************************************
32 #
33 # In many parts of the program, there is multiplexing of
34 # different kind of pointers in integers.
35 # Thats a thing we can do in 32-bit architectures
36 # ==> A register can have values up to 4 billion
37 # and thus, when used as an index of arrays, it
38 # can actually store much more.
39 #
40 # For example. Suppose a program is using foo[]s and
41 # zoo[]s and at some point we have something that may
42 # be either a foo or a zoo. That can be multiplexed
43 # into an integer 'x', where:
44 # if it is a foo, x = index in foo []
45 # if it is a zoo, x = 10000000 + index in zoo []
46 #
47 # This situation is common in many programs and 32-bit
48 # architectures are not only about "4Gb of memory"
49 #
50 # Here are basic indexes used:
51 #
52 # typeID: integer describing index in the types [] table of
53 # basetype+pointers/arrays/arguments
54 # ObjPtr: integer which multiplexes possible base-types into one
55 # Bitfield: if < -32
56 # Builtin: <BASETYPE> if < _BTLIMIT
57 # Structure: <RegionPtr> if < TYPEDEF_BASE && positive
58 # Typedef: <typeID> if > TYPEDEF_BASE
59 # in the latter case typeID = ObjPtr - TYPEDEF_BASE
60 # RegionPtr: integer describing index in regions [] table
61 # NormPtr: integer describing index in the CODE[] normalized C source
62 # ArglPtr: integer describing index in arglists[] table
63 # Symbol: integer describing value of CODE[]
64 #
65 *****************************************************************************/
66 bool INGLOBAL, INSTRUCT;
67 typeID VoidType, SIntType;
68 ArglPtr NoArgSpec;
69
70 /*****************************************************************************
71 # type pool (typeID)
72 #
73 # here we allocate types. Types of X are:
74 # int X
75 # int **X
76 # int * X [32][64][]
77 # struct foo *X
78 # int X (int, char*, struct bar**)
79 # struct foo **(*X[3]) (int, char)
80 #
81 # abstract declarations for the above are described with a
82 # 'struct type' object, which includes basetype (ObjPtr)
83 # and specifications (pointer, array-size, function-ArglistPtr).
84 # For example, the latter foo has specifications:
85 # '[', 3, '*', '(', <ArglPtr>, '*', '*', -1
86 # which sais: array 3 of pointer to function with arguments
87 # at <ArglPtr> returning pointer to pointer to basetype
88 #
89 # the types[] table, does not include typedef basetypes.
90 # typedefs are expanded before things are inserted into types[]
91 # with use of the gettype(type&) function.
92 *****************************************************************************/
93 static earray<type> types;
94 class utype;
95 static dbsTree<utype> typetree;
96 struct utype
97 {
98 utype *less, *more;
99 static type Query;
100 utype ();
101 typeID ID;
102 int compare (utype*);
103 int compare ();
104 };
105
106 utype::utype ()
107 {
108 typetree.addself (this);
109 ID = types.alloc ();
110 types.x [ID].base = Query.base;
111 types.x [ID].spec = intdup (Query.spec);
112 }
113
114 int base_of (typeID i)
115 {
116 return types.x [i].base;
117 }
118
119 int *spec_of (typeID i)
120 {
121 return types.x [i].spec;
122 }
123
124 type utype::Query;
125 int utype::compare (utype *u)
126 {
127 RegionPtr p = base_of (ID);
128 RegionPtr p2 = base_of (u->ID);
129 if (p == p2) return intcmp (spec_of (ID), spec_of (u->ID));
130 return p < p2 ? -1 : 1;
131 }
132
133 int utype::compare ()
134 {
135 RegionPtr p = base_of (ID);
136 RegionPtr p2 = Query.base;
137 if (p == p2) return intcmp (spec_of (ID), Query.spec);
138 return p < p2 ? -1 : 1;
139 }
140
141 typeID newtype (type &t)
142 {
143 utype::Query.base = t.base;
144 utype::Query.spec = t.spec;
145 utype *u = (utype*) typetree.dbsFind ();
146 if (!u) u = new utype;
147 return u->ID;
148 }
149
150 typeID gettype (type &t)
151 {
152 if (t.base < TYPEDEF_BASE) return newtype (t);
153
154 type nt;
155 typeID td = t.base - TYPEDEF_BASE;
156 int newspec [MSPEC];
157
158 // check incomplete typedef
159 intcpycat (newspec, t.spec, types.x [td].spec);
160 nt.base = base_of (td);
161 nt.spec = newspec;
162 return newtype (nt);
163 }
164
165 typeID gettype (int base, int *spec)
166 {
167 type t;
168 t.base = base;
169 t.spec = spec;
170 return gettype (t);
171 }
172
173 void opentype (typeID ti, type &t)
174 {
175 t.base = base_of (ti);
176 t.spec = spec_of (ti);
177 }
178 /*****************************************************************************
179 # argument lists.
180 #
181 # Array of typeIDs terminated at -1.
182 # also stored in a dbstree for log(N) insert
183 *****************************************************************************/
184 static earray<typeID*> arglists;
185 class argNode;
186 static dbsTree<argNode> argTree;
187
188 class argNode
189 {
190 public:
191 argNode *less, *more;
192 static Vspec Query;
193 argNode ();
194 int compare (argNode*);
195 int compare ();
196 ArglPtr ID;
197 };
198
199 Vspec argNode::Query;
200
201 int argNode::compare (argNode *d)
202 {
203 return intcmp (arglists.x [ID], arglists.x [d->ID]);
204 }
205
206 int argNode::compare ()
207 {
208 return intcmp (arglists.x [ID], Query);
209 }
210
211 argNode::argNode ()
212 {
213 argTree.addself (this);
214 ID = arglists.alloc ();
215 arglists.x [ID] = intdup (Query);
216 }
217
218 ArglPtr make_arglist (typeID *t)
219 {
220 argNode::Query = t;
221 argNode *a = argTree.dbsFind ();
222 if (!a) a = new argNode;
223 return a->ID;
224 }
225
226 typeID *ret_arglist (ArglPtr n)
227 {
228 return arglists.x [n];
229 }
230 /*****************************************************************************
231 # identifier lookup
232 #
233 # for each identifier, there is a list including:
234 # what this identifier is, and
235 # which region (scope) this applies to
236 # there is also an array of regions, each with the
237 # index of its parent region.
238 #
239 # with these, here we deal with lookups.
240 # Introducing new names in regions is done later.
241 #
242 # RECORD uses info.rp which shows which region it is about
243 # ENUMCONST uses info.eval for the value
244 # ENUMTAG is only useful for its existance
245 *****************************************************************************/
246 static RegionPtr current_region;
247
248 enum ITYPE {
249 RECORD, ENUMTAG, TYPEDEF, OBJECT, EOBJECT,
250 ENUMCONST, EFUNCTION, IFUNCTION
251 };
252 #define ISTAG(x) (x <= ENUMTAG)
253
254 static struct lookup_t {
255 lookup_t *next;
256 RegionPtr cp;
257 lookup_t (Symbol, ITYPE, RegionPtr);
258 union {
259 RegionPtr rp;
260 typeID tdf;
261 int eval;
262 bool fwd;
263 } info;
264 int placement;
265 char kind, incomplete, defspec;
266 } **lookup_table;
267
268 lookup_t::lookup_t (Symbol s, ITYPE i, RegionPtr r)
269 {
270 next = lookup_table [s - SYMBASE];
271 lookup_table [s - SYMBASE] = this;
272 kind = i;
273 cp = r;
274 }
275
276 struct memb_li
277 {
278 Symbol s;
279 memb_li *next;
280 };
281
282 enum REGION {
283 GLOBAL, CCODE, FUNCTIONAL, RECORD_S, RECORD_U
284 };
285
286 struct region {
287 RegionPtr parent;
288 REGION kind;
289 int aligned_top, nn;
290 char used, bits, incomplete;
291 NormPtr dcls, dcll;
292 memb_li *first, *last;
293 int add_object (typeID);
294 int add_field (typeID, typeID&);
295 void add_member (Symbol);
296 };
297 #define ISRECORD(x) (x >= RECORD_S)
298
299 int region::add_object (typeID t)
300 {
301 if (usage_only) return nn++;
302 if (kind == RECORD_U) {
303 int i = sizeof_typeID (t);
304 if (i > aligned_top) aligned_top = i;
305 return 0;
306 }
307 int r = aligned_top;
308 int i = sizeof_typeID (t);
309 nn++;
310 if (i == 0) ;
311 else if (i == 1) aligned_top++;
312 else if (i == 2) aligned_top += aligned_top % 2 ? 3 : 2;
313 else {
314 int a = aligned_top % 4;
315 if (a == 0) aligned_top += i;
316 else aligned_top += 4 - a + i;
317 }
318 return r;
319 }
320
321 int region::add_field (typeID ti, typeID &ret)
322 {
323 type t = types.x [ti];
324 type nt;
325 int spec [3] = { -1, 0, -1 }, r = aligned_top;
326
327 if (t.spec [1] == 0) {
328 bits = 0;
329 nt.base = S_INT;
330 spec [0] = '[';
331 nt.spec = spec;
332 ret = gettype (nt);
333 if (kind != RECORD_U) aligned_top += 4;
334 return r;
335 }
336 if ((bits += t.spec [1]) > BITFIELD_Q) {
337 bits = 0;
338 if (kind != RECORD_U) aligned_top += 4;
339 }
340 nt.base = -(bits + 32 * t.spec [1]);
341 nt.spec = spec;
342 ret = gettype (nt);
343 return r;
344 }
345
346 static mem_pool<region> regions;
347
348 void struct_location (typeID t, NormPtr s, int l)
349 {
350 regions [t].dcls = s;
351 regions [t].dcll = l;
352 }
353
354 static struct {
355 RegionPtr cc [32];
356 int cci;
357 } p_region;
358
359 RegionPtr open_region (RegionPtr r)
360 {
361 p_region.cc [p_region.cci++] = current_region;
362
363 current_region = r;
364 INGLOBAL = false;
365 INSTRUCT = ISRECORD (regions [r].kind);
366 return r;
367 }
368
369 RegionPtr new_region (REGION kind, RegionPtr r)
370 {
371 RegionPtr n;
372 regions [n = regions.alloc ()].parent = r;
373 regions [n].kind = kind;
374 regions [n].nn = regions [n].aligned_top = regions [n].bits = 0;
375 regions [n].incomplete = 1;
376 regions [n].used = 0;
377 regions [n].dcll = 0;
378 regions [n].first = regions [n].last = NULL;
379 return n;
380 }
381
382 RegionPtr open_region (REGION kind, RegionPtr r)
383 {
384 return open_region (new_region (kind, r));
385 }
386
387 void close_region ()
388 {
389 regions [current_region].incomplete = 0;
390 current_region = p_region.cc [--p_region.cci];
391 INGLOBAL = current_region == 0;
392 INSTRUCT = !INGLOBAL && ISRECORD (regions [current_region].kind);
393 }
394
395 lookup_t *Lookup (Symbol s, bool tagged, RegionPtr r)
396 {
397 lookup_t *t = lookup_table [s - SYMBASE];
398
399 if (tagged) for (; t; t = t->next) {
400 if (t->cp == r && ISTAG(t->kind)) {
401 regions [r].used = 1;
402 return t;
403 }
404 } else for (; t; t = t->next)
405 if (t->cp == r && !ISTAG(t->kind)) {
406 regions [r].used = 1;
407 return t;
408 }
409
410 return NULL;
411 }
412
413 lookup_t *Lookup_foruse (Symbol s, bool tagged, RegionPtr r)
414 {
415 lookup_t *t;
416 for (;;) {
417 if ((t = Lookup (s, tagged, r))) return t;
418 if (r == 0) break;
419 r = regions [r].parent;
420 }
421 return NULL;
422 }
423 /*****************************************************************************
424 # small utility : comparison of types
425 #
426 # Normally, comparison one by one would be plentyly enough, but a
427 # function declaration w/o arguments is a wildcard that should
428 # match with any other argument list
429 # Moreover, incomplete arrays match with complete arrays
430 *****************************************************************************/
431 static Ok speccmp (Vspec s1, Vspec s2)
432 {
433 while (*s1 != -1) {
434 if (*s1 != *s2) return false;
435 if (*s1 == '(') {
436 ++s1, ++s2;
437 // In the very rare case of:
438 // "int foo (float*);"
439 // "typedef float v3d [3];"
440 // "int foo (v3d x) { ... }"
441 // we will fail.
442 // Instead of fixing, comment out.
443 //if (*s1 != *s2 && *s1 != NoArgSpec && *s2 != NoArgSpec)
444 //return false;
445 } else if (*s1 == '[') {
446 ++s1, ++s2;
447 // why bother?
448 //if (*s1 != *s2 && *s1 != 0 && *s2 != 0)
449 //return false;
450 }
451 ++s1, ++s2;
452 }
453 return *s1 == *s2;
454 }
455
456 static Ok typecmp (typeID ti1, typeID ti2)
457 {
458 type t1 = types.x [ti1];
459 type t2 = types.x [ti2];
460
461 return t1.base == t2.base && speccmp (t1.spec, t2.spec);
462 }
463 /******************************************************************************
464 # functions
465 #
466 # functions are compiled after global has been parsed
467 # so that in expressions we know which variables are external.
468 #
469 # At each function definition, we store the location to the
470 # function body and the function arguments in CODE[].
471 #
472 # after the entire translation unit, function_no()
473 # will be called for each function, which will return the
474 # pointers to argument list, function body and open a
475 # region ready to receive the argument objects.
476 ******************************************************************************/
477 struct cfunc {
478 Symbol name;
479 NormPtr args, body, ends, txt;
480 };
481
482 static earray<cfunc> functions;
483
484 Ok function_definition (Symbol name, NormPtr args, NormPtr body, NormPtr ends, NormPtr txt)
485 {
486 int i;
487 lookup_t *L = Lookup (name, false, 0);
488
489 if (L->kind != EFUNCTION) return false;
490 L->kind = IFUNCTION;
491
492 i = functions.alloc ();
493 functions.x [i].name = name;
494 functions.x [i].args = args;
495 functions.x [i].body = body;
496 functions.x [i].ends = ends;
497 functions.x [i].txt = txt;
498 L->placement = i;
499 return true;
500 }
501
502 Ok function_no (int i, NormPtr *ra, NormPtr *rb)
503 {
504 if (i >= functions.nr) return false;
505 *ra = functions.x [i].args;
506 *rb = functions.x [i].body;
507 open_region (FUNCTIONAL, 0);
508 ncc->new_function (functions.x [i].name);
509 return true;
510 }
511
512 void open_compound ()
513 {
514 open_region (CCODE, current_region);
515 }
516
517 void functions_of_file ()
518 {
519 int prevfile = -1;
520 PRINTF ("\n\n");
521 for (int i = 0; i < functions.nr; i++) {
522 if (cfile_of (functions.x [i].body) != prevfile)
523 PRINTF ("\nP: %s\n", C_Files [prevfile =
524 cfile_of (functions.x [i].body)].file);
525 PRINTF ("L: %s() %i %i\n",
526 expand (functions.x [i].name),
527 cline_of (functions.x [i].txt),
528 cline_of (functions.x [i].ends));
529 }
530 }
531 /*****************************************************************************
532 #
533 # Structure member list. This was not included until 1.1
534 # It's needed in initializers where we have to assign values
535 # to members in their natural order or by designators
536 #
537 *****************************************************************************/
538 void region::add_member (Symbol s)
539 {
540 memb_li *m = new memb_li;
541 m->s = s;
542 m->next = NULL;
543 if (!first) {
544 first = last = m;
545 } else {
546 last->next = m;
547 last = m;
548 }
549 }
550 /*****************************************************************************
551 # declaration of new names to the program
552 #
553 # which are: objects (variables and functions), typedefs
554 # enumeration tags, enumeration constants and structure tags.
555 #
556 # structure tag can be declared at declaration or at forward
557 # declaration (use). Check for recursion (incomplete base type), is
558 # done at the sizeof calculation elsewhere.
559 #
560 # the items are semantically correct, and the only error that
561 # can happen here is if something is already declared
562 # in the same region
563 *****************************************************************************/
564
565 static Ok function_declaration (Symbol s, typeID t, VARSPC v)
566 {
567 lookup_t *L;
568
569 if ((L = Lookup (s, false, 0))) {
570 if (L->kind < EFUNCTION) return false;
571 typeID tt = L->info.tdf;
572 if (!typecmp (t, tt)) return false;
573 if (L->kind == EFUNCTION && spec_of (tt)[1] == NoArgSpec)
574 L->info.tdf = t;
575 return true;
576 }
577
578
579 L = new lookup_t (s, EFUNCTION, 0);
580 L->info.tdf = t;
581 L->defspec = v;
582 return true;
583 }
584
585 static Ok field_member (Symbol s, typeID t)
586 {
587 typeID nt;
588 int p;
589
590 if (s != -1 && Lookup (s, false, current_region))
591 return false;
592 p = regions [current_region].add_field (t, nt);
593 if (s != -1) {
594 lookup_t *L = new lookup_t (s, OBJECT, current_region);
595 L->info.tdf = nt;
596 L->placement = p;
597 }
598 return true;
599 }
600
601 Ok introduce_obj (Symbol s, typeID t, VARSPC v = DEFAULT)
602 {
603 if (ISFUNCTION (types.x [t]))
604 return function_declaration (s, t, v);
605
606 if (INSTRUCT) regions [current_region].add_member (s);
607 if (spec_of (t)[0] == ':')
608 return field_member (s, t);
609
610 lookup_t *L;
611 if ((L = Lookup (s, false, current_region))) {
612 if (L->kind != EOBJECT && L->kind != OBJECT) return false;
613 typeID et = L->info.tdf;
614 if (!typecmp (t, et)) return false;
615 //if (current_region == 0) return true;
616 if (spec_of (et)[0] == '[' && spec_of (et)[1] == 0) {
617 //if (L->kind == OBJECT) {
618 L->info.tdf = t;
619 return true;
620 //}
621 //L->kind = OBJECT;
622 //L->placement = regions
623 // [current_region].add_object (t);
624 //return true;
625 }
626 //if (L->kind == OBJECT) return v == EXTERN;
627 if (v != EXTERN) {
628 // instantiation
629 L->kind = OBJECT;
630 L->info.tdf = t;
631 L->placement = regions
632 [current_region].add_object (t);
633 }
634 return true;
635 }
636
637 if (v == EXTERN) {
638 L = new lookup_t (s, EOBJECT, current_region);
639 L->info.tdf = t;
640 } else {
641 L = new lookup_t (s, OBJECT, current_region);
642 L->info.tdf = t;
643 L->placement = regions
644 [current_region].add_object (t);
645 }
646
647 return true;
648 }
649
650 Ok introduce_tdef (Symbol s, typeID t)
651 {
652 lookup_t *L = Lookup (s, false, current_region);
653 if (L) return L->kind == TYPEDEF && typecmp (t, L->info.tdf);
654 L = new lookup_t (s, TYPEDEF, current_region);
655 L->info.tdf = t;
656 return true;
657 }
658
659 ObjPtr lookup_typedef (Symbol s)
660 {
661 lookup_t *t = Lookup_foruse (s, false, current_region);
662 if ((t) && t->kind == TYPEDEF)
663 return TYPEDEF_BASE + t->info.tdf;
664 RegionPtr r = current_region;
665 do {
666 r = regions [r].parent;
667 t = Lookup_foruse (s, false, r);
668 if ((t) && t->kind == TYPEDEF)
669 return TYPEDEF_BASE + t->info.tdf;
670 } while (r);
671 return -1;
672 }
673
674 Ok is_typedef (Symbol s)
675 {
676 lookup_t *t = Lookup_foruse (s, false, current_region);
677 return (t) && t->kind == TYPEDEF;
678 }
679
680 Ok introduce_enumconst (Symbol s, int value)
681 {
682 RegionPtr r = current_region;
683 while (ISRECORD (regions [r].kind)) r = regions [r].parent;
684 if (Lookup (s, false, r)) return false;
685 lookup_t *L = new lookup_t (s, ENUMCONST, r);
686 L->info.eval = value;
687 return true;
688 }
689
690 Ok introduce_enumtag (Symbol s, bool fwd)
691 {
692 lookup_t *L = Lookup (s, true, current_region);
693 if (L)
694 if (!L->info.fwd)
695 return false;
696 else L->info.fwd = fwd;
697 else {
698 L = new lookup_t (s, ENUMTAG, current_region);
699 L->info.fwd = fwd;
700 }
701 return true;
702 }
703
704 Ok valid_enumtag (Symbol s)
705 {
706 lookup_t *t = Lookup_foruse (s, true, current_region);
707 return (t) && t->kind == ENUMTAG;
708 }
709
710 /******************************************************************************
711 # records (struct, union)
712 #
713 # Normally, structure by name is not needed. But in the
714 # case of usage report the user wants to know which
715 # structure is structure #234
716 # Thus the inttree.
717 ******************************************************************************/
718 static intTree struct_names;
719 class sname : public intNode
720 {
721 public:
722 int symbol;
723 sname (int s) : intNode (&struct_names) { symbol = s; }
724 };
725
726 Symbol struct_by_name (RegionPtr p)
727 {
728 sname *s = (sname*) struct_names.intFind (p);
729 return !s ? -2 : s->symbol;
730 }
731
732 bool rename_struct (typeID t, Symbol s)
733 {
734 sname *sn = (sname*) struct_names.intFind (base_of (t));
735 if (sn && sn->symbol == -1)
736 sn->symbol = s;
737 return true;
738 }
739
740 static inline void name_struct (RegionPtr p, Symbol s)
741 {
742 if (usage_only) if (!struct_names.intFind (p)) new sname (s);
743 }
744
745 //#
746 //# Show structure declaration locations
747 //#
748 void structs_of_file ()
749 {
750 int i, n = regions.nr ();
751 int prevfile = -1;
752 PRINTF ("\n");
753
754 for (i = 0; i < n; i++)
755 if (regions [i].used && regions [i].dcll) {
756 if (cfile_of (regions [i].dcls) != prevfile)
757 PRINTF ("\nP: %s\n", C_Files [prevfile =
758 cfile_of (regions [i].dcls)].file);
759 PRINTF ("Y: %s %i %i\n",
760 expand (struct_by_name (i)),
761 cline_of (regions [i].dcls),
762 cline_of (regions [i].dcls + regions [i].dcll));
763 }
764 }
765 //
766 //
767 //
768
769 RegionPtr introduce_anon_struct (bool isst)
770 {
771 RegionPtr r;
772 for (r = current_region; ISRECORD (regions [r].kind);
773 r = regions [r].parent);
774 r = open_region (new_region (isst ? RECORD_S : RECORD_U, r));
775 name_struct (r, -1);
776 return r;
777 }
778
779 RegionPtr introduce_named_struct (Symbol s, bool isst)
780 {
781 RegionPtr r;
782 lookup_t *L;
783 for (r = current_region; ISRECORD (regions [r].kind);
784 r = regions [r].parent);
785
786 L = Lookup_foruse (s, true, r);
787 if (L) {
788 if (L->kind == ENUMTAG) return -1;
789 name_struct (L->info.rp, s);
790 return open_region (L->info.rp);
791 }
792 L = new lookup_t (s, RECORD, r);
793 L->incomplete = 0;
794 L->info.rp = open_region (isst ? RECORD_S:RECORD_U, r);
795 name_struct (L->info.rp, s);
796 return L->info.rp;
797 }
798
799 RegionPtr use_struct_tag (Symbol s, bool isst)
800 {
801 RegionPtr r;
802 lookup_t *L;
803 for (r = current_region; ISRECORD (regions [r].kind);
804 r = regions [r].parent);
805 L = Lookup_foruse (s, true, r);
806 if (L) return (L->kind == ENUMTAG) ? -1 : L->info.rp;
807 L = new lookup_t (s, RECORD, r);
808 L->incomplete = 1;
809 return L->info.rp = new_region (isst ? RECORD_S : RECORD_U, r);
810 }
811
812 RegionPtr fwd_struct_tag (Symbol s, bool isst)
813 {
814 RegionPtr r;
815 lookup_t *L;
816 for (r = current_region; ISRECORD (regions [r].kind);
817 r = regions [r].parent);
818 L = Lookup (s, true, r);
819 if (L) return (L->kind == ENUMTAG) ? -1 : L->info.rp;
820 L = new lookup_t (s, RECORD, r);
821 L->incomplete = 1;
822 return L->info.rp = new_region (isst ? RECORD_S : RECORD_U, r);
823 }
824
825 /*****************************************************************************
826 # lookup_object
827 #
828 # this is the kind of lookup needed in expressions.
829 # expressions do not need: structure tags, typedefs, etc
830 # but only objects or enumeration constants
831 #
832 # for functions there is the additional rule that if a
833 # declaration does not exist, it is implictly declared as
834 # extern int f ();
835 #
836 # for structure members it is the same but the lookup is
837 # restricted only inside the scope and it does not do it's best
838 # to find a matching declaration
839 #
840 # have_function is like lookup_function except the function
841 # is not declared if it doesn't exist
842 *****************************************************************************/
843 lookup_object::lookup_object (Symbol s, bool f2ptr)
844 {
845 lookup_t *L;
846
847 if (!(L = Lookup_foruse (s, false, current_region)))
848 half_error ("Undefined object", expand (s));
849
850 if ((enumconst = L->kind == ENUMCONST)) {
851 ec = L->info.eval;
852 return;
853 }
854
855 typeID t = L->info.tdf;
856 base = types.x [t].base;
857 if (L->kind == OBJECT) {
858 FRAME = L->cp;
859 displacement = L->placement;
860 intcpy (spec, spec_of (t));
861 } else if (L->kind == EOBJECT) {
862 FRAME = -1;
863 displacement = 0;
864 intcpy (spec, spec_of (t));
865 } else if (L->kind == IFUNCTION || L->kind == EFUNCTION) {
866 FRAME = -1;
867 displacement = L->placement;
868 if (f2ptr) {
869 spec [0] = '*';
870 intcpy (spec + 1, spec_of (t));
871 } else
872 intcpy (spec, spec_of (t));
873 } else half_error ("Undefined object", expand (s));
874 }
875
876 lookup_function::lookup_function (Symbol s, bool fatalerror)
877 {
878 lookup_t *L;
879
880 found = true;
881 ARGFUNC = fptr = false;
882 if (!(L = Lookup_foruse (s, false, current_region))) {
883 type t;
884 spec [0] = '(', spec [1] = NoArgSpec, spec [2] = -1;
885 base = t.base = S_INT;
886 t.spec = spec;
887 introduce_obj (s, gettype (t), EXTERN);
888 FRAME = -1;
889 displacement = 0;
890 } else if (L->kind == EFUNCTION) {
891 FRAME = -1;
892 displacement = 0;
893 typeID t = L->info.tdf;
894 base = base_of (t);
895 intcpy (spec, spec_of (t));
896 } else if (L->kind == IFUNCTION) {
897 FRAME = -1;
898 displacement = L->placement;
899 typeID t = L->info.tdf;
900 base = base_of (t);
901 intcpy (spec, spec_of (t));
902 } else if (L->kind == EOBJECT || L->kind == OBJECT) {
903 typeID t = L->info.tdf;
904 if (!(types.x [t].spec [0] == '*'
905 && types.x [t].spec [1] == '('))
906 if (fatalerror)
907 half_error ("Not a pointer to function", expand (s));
908 else
909 intcpy (spec, spec_of (t));
910 else
911 intcpy (spec, spec_of (t) + 1);
912 base = base_of (t);
913 FRAME = L->cp;
914 ARGFUNC = FRAME && !regions [FRAME].parent;
915 displacement = L->placement;
916 fptr = true;
917 } else if (fatalerror)
918 half_error ("Not a function", expand (s));
919 else found = false;
920 }
921
922 lookup_member::lookup_member (Symbol s, RegionPtr r)
923 {
924 lookup_t *L = Lookup (s, false, r);
925
926 if (!L) half_error ("Undefined member", expand (s));
927
928 displacement = L->placement;
929 typeID t = L->info.tdf;
930 base = base_of (t);
931 intcpy (spec, spec_of (t));
932 }
933
934 void spill_anonymous (RegionPtr r)
935 {
936 memb_li *m;
937 for (m = regions [r].first; m; m=m->next) {
938 lookup_t *L = Lookup (m->s, false, r);
939 if (L->kind == OBJECT)
940 introduce_obj (m->s, L->info.tdf);
941 }
942 }
943
944 bool have_function (Symbol s)
945 {
946 lookup_t *L = Lookup_foruse (s, false, current_region);
947 return L && (L->kind == EFUNCTION || L->kind == IFUNCTION);
948 }
949 /*****************************************************************************
950 # sizeof
951 #
952 # - esizeof_objptr (), is used for the case the sizeof the
953 # base declarator is needed to compute the size of an incomplete
954 # type from initializer. For example:
955 #
956 # typedef struct { int x, y } foo;
957 # foo bar [] = { 1, 2, 3, 4, 5, 6 };
958 # were bar is array [3] of struct foo.
959 #
960 # - sizeof_typeID (), is used by sizeof (typename)
961 #
962 # - the function ptr_incremenet () take as an argument a type
963 # which MUST be a pointer to something, and return how
964 # much will the ++ operator on the pointer increase it.
965 ******************************************************************************/
966 static bool just_count;
967
968 static const int sizez [] = {
969 sizeof (char), sizeof (char), sizeof (short int), sizeof (short int),
970 sizeof (int), sizeof (int), sizeof (long int), sizeof (long int),
971 sizeof (long long), sizeof (long long), sizeof (float),
972 sizeof (double), 0
973 };
974
975 static inline int sizeof_btype (BASETYPE b)
976 {
977 return (just_count) ? 1 : sizez [b - S_CHAR];
978 }
979
980 static inline int sizeof_ptr ()
981 {
982 return (just_count) ? 1 : sizeof (void*);
983 }
984
985 static int sizeof_struct (RegionPtr p)
986 {
987 if (regions [p].incomplete)
988 syntax_error (ExpressionPtr, "incomplete structure");
989 return (just_count) ? regions [p].nn : regions [p].aligned_top;
990 }
991
992 static int sizeof_type (type &t)
993 {
994 int i, na = 1, st, *spec = t.spec;
995
996 if (spec [0] == '(') return 0;
997
998 for (i = 0; spec [i] == '['; i += 2)
999 na *= spec [i + 1];
1000
1001 //if (!na) half_error ("sizeof Incomplete type attempted");
1002
1003 st = (spec [i] == '*') ? sizeof_ptr ()
1004 : (T_BASETYPE (t)) ? sizeof_btype ((BASETYPE) t.base)
1005 : sizeof_struct (t.base);
1006
1007 return na * st;
1008 }
1009
1010 int sizeof_typeID (typeID ti)
1011 {
1012 type t = types.x [ti];
1013 return sizeof_type (t);
1014 }
1015 // *************************************************
1016
1017 int esizeof_objptr (ObjPtr o)
1018 {
1019 if (o < _BTLIMIT) return 1;
1020
1021 just_count = true;
1022 int r = (o < TYPEDEF_BASE) ? sizeof_struct (o) :
1023 sizeof_typeID (o - TYPEDEF_BASE);
1024 just_count = false;
1025 return r;
1026 }
1027
1028 int sizeof_type (int base, Vspec spec)
1029 {
1030 type t;
1031 t.base = base;
1032 t.spec = spec;
1033 return sizeof_type (t);
1034 }
1035
1036 int ptr_increment (int b, Vspec spec)
1037 {
1038 type t;
1039 int tspec [50];
1040
1041 if (spec [0] == -1)
1042 half_error ("invalid pointer arithmetic");
1043
1044 t.base = b;
1045 intcpy (tspec, spec [0] == '*' ? spec + 1: spec + 2);
1046 t.spec = tspec;
1047
1048 return sizeof_type (t);
1049 }
1050
1051 /*****************************************************************************
1052 #
1053 # initialization of various things
1054 #
1055 *****************************************************************************/
1056 void init_cdb ()
1057 {
1058 lookup_table = new lookup_t* [C_Nsyms];
1059 for (int i = 0; i < C_Nsyms; i++)
1060 lookup_table [i] = NULL;
1061
1062 // global, region 0, parent of self, etc
1063 open_region (GLOBAL, 0);
1064 INGLOBAL = true;
1065
1066 // Void type
1067 int x [1];
1068 x [0] = -1;
1069 type t = { VOID, &x[0] };
1070 VoidType = newtype (t);
1071 t.base = S_INT;
1072 SIntType = newtype (t);
1073
1074 // argument list with no arguments --old style
1075 typeID ta [2];
1076 ta [0] = ARGLIST_OPEN; ta [1] = -1;
1077 NoArgSpec = make_arglist (ta);
1078 ta [0] = SIntType;
1079 ArglPtr sizet_arg = make_arglist (ta);
1080
1081 #define DEFBUILTIN(B, S1, S2, S3, S4, T) \
1082 if (ccbuiltins.bt ## B!= -1) {\
1083 int s [] = { S1, S2, S3, S4 }; type t;\
1084 t.base = T; t.spec = s;\
1085 introduce_obj (ccbuiltins.bt ## B, gettype (t), STATIC);\
1086 }
1087
1088 DEFBUILTIN(__FUNCTION__, '*', -1, -1, -1, S_CHAR)
1089 DEFBUILTIN(__func__, '*', -1, -1, -1, S_CHAR)
1090 DEFBUILTIN(__PRETTY_FUNCTION__, '*', -1, -1, -1, S_CHAR)
1091 DEFBUILTIN(__builtin_return_address, '(', NoArgSpec, '*', -1, VOID)
1092 DEFBUILTIN(__builtin_alloca, '(', sizet_arg, '*', -1, VOID)
1093 }
1094
1095 //
1096 // this routine here, shows what is included in the lookup table ---
1097 // useful for debugging cdb
1098 //
1099
1100 void show_lookups ()
1101 {
1102 lookup_t *L;
1103 int i;
1104
1105 for (i = 0; i < C_Nsyms; i++) {
1106 PRINTF ("* * * * * Symbol [%s]\n", C_Syms [i]);
1107 for (L = lookup_table [i]; L; L = L->next) {
1108 PRINTF ("- Inside %i: ", L->cp);
1109 switch (L->kind) {
1110 case RECORD:
1111 PRINTF ("Record no %i\n", L->info.rp);
1112 break;
1113 case ENUMTAG:
1114 PRINTF ("Enumeration tag\n");
1115 break;
1116 case TYPEDEF:
1117 PRINTF ("typedef\n");
1118 printtype (L->info.tdf);
1119 break;
1120 case OBJECT:
1121 case EOBJECT:
1122 PRINTF ("variable %i\n", L->placement);
1123 printtype (L->info.tdf);
1124 break;
1125 case ENUMCONST:
1126 PRINTF ("enumeration constant %i\n", L->info.eval);
1127 break;
1128 case EFUNCTION:
1129 case IFUNCTION:
1130 PRINTF ("function %i\n", L->placement);
1131 printtype (L->info.tdf);
1132 break;
1133 default:;
1134 } }
1135 }
1136 }
1137
1138 /**************************************************************************
1139 # expand the fields of an aggregate type for initializer
1140 #
1141 # The reason for the complexity of the code below, is the Standard
1142 # P = { .x.y { 2, [1].e.[1] { 32 }, 27 }, };
1143 # is a valid initializer. But where shall '27' be assigned?
1144 #
1145 # ISOC99 sais:
1146 # ``30. Note that the fully bracketed and minimally bracketed
1147 # form of initalization are, in general, less likely to cause
1148 # confusion''
1149 # which is translated to :
1150 # ``Don't do initializations like P because we are not sure
1151 # if your compiler can implement this correctly''
1152 #
1153 # Hopefully this works
1154 ***************************************************************************/
1155
1156 class aeqn {
1157 Symbol txt [1024];
1158 int txti;
1159 void prstruct (RegionPtr);
1160 void prarr (int,int*);
1161 public:
1162 aeqn (Symbol);
1163 Symbol *dclstr;
1164 };
1165
1166 #define UNI '/'
1167
1168 void aeqn::prstruct (RegionPtr p)
1169 {
1170 int base, *spec;
1171 lookup_t *L;
1172 memb_li *m;
1173
1174 if (regions [p].kind == RECORD_U)
1175 txt [txti++] = UNI;
1176 for (m = regions [p].first; m; m=m->next) {
1177 L = Lookup (m->s, false, p);
1178 txt [txti++] = m->s;
1179 base = base_of (L->info.tdf);
1180 spec = spec_of (L->info.tdf);
1181 txt [txti++] = '{';
1182 if (spec [0] == '[')
1183 prarr (base, spec);
1184 else if (spec [0] == -1 && base > _BTLIMIT)
1185 prstruct (base);
1186 else txt [txti++] = '!';
1187 txt [txti++] = '}';
1188 }
1189 }
1190
1191 void aeqn::prarr (int base, int *spec)
1192 {
1193 txt [txti++] = INUMBER + spec[1];
1194 txt [txti++] = '[';
1195 if (spec [2] == '[') prarr (base, spec+2);
1196 else if (spec [2] == -1 && base > _BTLIMIT)
1197 prstruct (base);
1198 else txt [txti++] = '!';
1199 txt [txti++] = ']';
1200 }
1201
1202 aeqn::aeqn (Symbol s)
1203 {
1204 lookup_t *L = Lookup (s, false, current_region);
1205 int base, *spec;
1206 base = base_of (L->info.tdf);
1207 spec = spec_of (L->info.tdf);
1208 txt [0] = s;
1209 txt [1] = '{';
1210 txti = 2;
1211 if (spec [0] == '[') prarr (base, spec);
1212 else if (spec [0] == -1 && base > _BTLIMIT)
1213 prstruct (base);
1214 txt [txti++] = '}';
1215 txt [txti++] = -1;
1216 memcpy (dclstr = new int [txti], txt, txti * sizeof (txt [0]));
1217 }
1218
1219 Symbol *mk_dclstr (Symbol s)
1220 {
1221 aeqn A (s);
1222 if (0) {
1223 int i;
1224 PRINTF ("[XYZZY]: ");
1225 for (i = 0; A.dclstr [i] != -1; i++)
1226 PRINTF ("%s", expand (A.dclstr[i]));
1227 PRINTF ("\t\t(txtlen=%i,i=%s)\n", i,expand(s));
1228 }
1229 return A.dclstr;
1230 }
1231
1232 dcle::dcle (Symbol s)
1233 {
1234 dclstr = mk_dclstr (s);
1235 p = 0;
1236 ni = -1;
1237 }
1238
1239 dcle::~dcle ()
1240 {
1241 delete [] dclstr;
1242 }
1243
1244 #define PRFUN(x) \
1245 //printf("Entering "#x"\t at %i [%s]",p,expand(dclstr[p]));printf(" [%s]",expand(dclstr[p+1]));printf(" [%s]\n",expand(dclstr[p+2]));
1246
1247
1248 NormPtr dcle::skipbracket (NormPtr p)
1249 {
1250 PRFUN(skipbracket)
1251 // ts is '[' or '{'
1252 Symbol ts = dclstr [p++];
1253 Symbol tc = ts == '[' ? ']' : '}';
1254 int c;
1255 for (c = 1; c; p++)
1256 if (dclstr [p] == ts) c++;
1257 else if (dclstr [p] == tc) c--;
1258 return p;
1259 }
1260
1261 void dcle::openarray ()
1262 {
1263 PRFUN(openarray)
1264 nests [++ni].max = dclstr [p++] - INUMBER;
1265 nests [ni].c = 0;
1266 nests [ni].p = p++;
1267 nests [ni].marked = false;
1268 }
1269
1270 void dcle::openstruct ()
1271 {
1272 PRFUN(openstruct)
1273 nests [++ni].s = dclstr [p++];
1274 nests [ni].p = p++;
1275 nests [ni].max = -1;
1276 nests [ni].marked = false;
1277 }
1278
1279 bool dcle::opennest ()
1280 {
1281 PRFUN(opennest)
1282 // nested types open with '2[' or 'x{'
1283 // for arrays and structures
1284 if (dclstr [p] >= INUMBER) openarray ();
1285 else if (ISSYMBOL (dclstr [p])) openstruct ();
1286 else if (dclstr [p] == '[') p++;
1287 else return false;
1288 if (dclstr [p] == UNI) p++;
1289 return true;
1290 }
1291
1292 bool dcle::open_bracket ()
1293 {
1294 PRFUN(open_bracket)
1295 // marks the nested type
1296 if (!opennest ()) return false;
1297 nests [ni].marked = true;
1298 return true;
1299 }
1300
1301 bool dcle::close_bracket ()
1302 {
1303 PRFUN(close_bracket)
1304
1305 // takes you at the closing bracket of the
1306 // topmost marked nested type
1307 while (ni >= 0 && !nests [ni].marked)
1308 ni--;
1309 if (ni <= 0) return
1310 false;
1311 nests [ni].marked = false;
1312 p = skipbracket (nests [ni].p) - 1;
1313 return true;
1314 }
1315
1316 bool dcle::closenest ()
1317 {
1318 PRFUN(closenest)
1319 // closes a nested type and takes you after it
1320 // or recycle in the case of array
1321 if (dclstr [p] == '}') {
1322 if (nests [ni].marked)
1323 return false;
1324 ni--;
1325 p++;
1326 return true;
1327 }
1328 if (nests [ni].marked) return
1329 false;
1330 if (++nests [ni].c < nests [ni].max || nests [ni].max == 0) {
1331 /* direct-declarator [] without constant-expression is assumed to accept any number
1332 of initializers in initializer-list.
1333
1334 Ben Lau <benlau@linux.org.hk> */
1335
1336 p = nests [ni].p;
1337 return true;
1338 }
1339 ni--;
1340 p++;
1341 return true;
1342 }
1343
1344 bool dcle::comma ()
1345 {
1346 PRFUN(comma)
1347 // takes you to the next point of interest
1348 if (dclstr [p] == '!') p++;
1349 again:
1350 while (dclstr [p] == '}' || dclstr [p] == ']')
1351 if (!closenest ()) return true;
1352 if (dclstr [nests [ni].p + 1] == UNI && dclstr [p] != '[') {
1353 int po = p = skipbracket (nests [ni].p) - 1;
1354 if (closenest () && po < p)
1355 goto again;
1356 }
1357 return true;
1358 }
1359
1360 bool dcle::tofield ()
1361 {
1362 PRFUN(tofield)
1363 // takes you to the next '!'
1364 int dp;
1365 while ((dp = dclstr [p]) != '!')
1366 if (opennest ()) continue;
1367 else if (dp == ']' || dp == '}') {
1368 if (!closenest ()) return
1369 false;
1370 } else return false;
1371 return true;
1372 }
1373
1374 bool dcle::designator (Symbol D[])
1375 {
1376 PRFUN(designator)
1377 // takes you where the designator points
1378 int i;
1379 while (ni >= 0 && !nests [ni].marked)
1380 ni--;
1381 if (dclstr [p = nests [ni].p + 1] == UNI) p++;
1382 for (i = 0; D [i] != -1; i++)
1383 if (ISSYMBOL (D [i])) {
1384 while (ISSYMBOL (dclstr [p]) && dclstr [p] != D [i])
1385 p = skipbracket (p + 1);
1386 if (dclstr [p] != D [i]) return
1387 false;
1388 if (D [i+1] != -1) opennest ();
1389 } else {
1390 if (nests [ni].max != -1) {
1391 if (D [i] < INUMBER) D [i] = nests [ni].max;//hack
1392 nests [ni].c = D [i] - INUMBER;
1393 if (dclstr [p = nests [ni].p + 1] == UNI)
1394 p++;
1395 } else {
1396 if (!opennest ()) return false;
1397 if (D [i] < INUMBER) D [i] = nests [ni].max;//hack
1398 nests [ni].c = D [i] - INUMBER;
1399 if (D [i+1] == -1)
1400 if (dclstr [--p] == UNI) p--;
1401 // br0ken standard *&#@*#@&^%&
1402 }
1403 }
1404 return true;
1405 }
1406
1407 bool dcle::tostruct (RegionPtr)
1408 {
1409 PRFUN(tostruct)
1410 // this is done the lazy way
1411 // struct { struct { struct { int a, b; } S1; } S2; }
1412 // S3 = { ((struct S1) {1,2}) };
1413 // is not supported and ?maybe? rightly so
1414 if (!ISSYMBOL (dclstr [p])) return false;
1415 opennest ();
1416 p = skipbracket (nests [ni].p) - 1;
1417 return true;
1418 }
1419
1420 Symbol *dcle::mk_current ()
1421 {
1422 PRFUN(mk_current)
1423 // create the current field as a postfix expression
1424 int i, p;
1425 for (i = 0, p = 0; i <= ni; i++)
1426 if (nests [i].max != -1) {
1427 pexpr [p++] = '[';
1428 pexpr [p++] = INUMBER + nests [i].c;
1429 pexpr [p++] = ']';
1430 } else {
1431 pexpr [p++] = '.';
1432 pexpr [p++] = nests [i].s;
1433 }
1434 pexpr [p++] = ';';
1435 pexpr [p] = -1;
1436 return &pexpr [1];
1437 }
1438
1439 void dcle::printexpr ()
1440 {
1441 // debug routine
1442 int i;
1443 PRINTF ("XYZZY: ");
1444 for (i=0;pexpr[i]!=-1;i++)
1445 PRINTF ("%s", expand (pexpr [i]));
1446 PRINTF ("\t\t%i\n", i);
1447 }
1448 /*****************************************************************************
1449
1450 *****************************************************************************/
1451
1452 void showdb ()
1453 {
1454 //show_lookups ();
1455 PRINTF ("#%i types\n", types.nr);
1456 PRINTF ("#%i arglists\n", arglists.nr);
1457 PRINTF ("#%i regions\n", regions.nr ());
1458 PRINTF ("#%i function definitions\n", functions.nr);
1459
1460 }
1461
1462 //****************************************************************************
1463 // debugging routine, print a type
1464 //****************************************************************************
1465
1466 #define U "unsigned "
1467 #define S "short "
1468 #define L "long "
1469 #define I "int"
1470 #define C "char"
1471
1472 static const char *btn [] = {
1473 // some ppl are lazy
1474 C, U C, S I, U S I, I, U I, L I,
1475 U L I, L L, U L L, "float", "double", "void"
1476 };
1477
1478 void printtype (int base, int *spec)
1479 {
1480 #define STDE stderr
1481 int i;
1482 if (base < -32) fprintf (STDE, "blitfield\n");
1483 else if (base < _BTLIMIT) fprintf (STDE, "%s ", btn [base - S_CHAR]);
1484 else fprintf (STDE, "record #%i ", base);
1485 for (i = 0; spec [i] != -1; i++)
1486 if (spec [i] == '*') fprintf (STDE, "*");
1487 else if (spec [i] == '[')
1488 fprintf (STDE, "[%i]", spec [++i]);
1489 else if (spec [i] == '(')
1490 fprintf (STDE, "(%i)", spec [++i]);
1491 else if (spec [i] == ':')
1492 fprintf (STDE, ":%i", spec [++i]);
1493 else { printf ("fuck %i", spec [i]); break; }
1494 fprintf (STDE, "\n");
1495 }
1496
1497 void printtype (typeID ti)
1498 {
1499 type t = types.x [ti];
1500 printtype (t.base, t.spec);
1501 }