Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110623134125

Diff

Diff from 1.21 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/symtabs.c

Annotated File View

ragge
1.21
1 /*      $Id: symtabs.c,v 1.21 2011/06/23 13:41:25 ragge Exp $   */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 #include "pass1.h"
31
ragge
1.3
32 /*
33  * These definitions are used in the patricia tree that stores
34  * the strings.
35  */
ragge
1.1
36 #define LEFT_IS_LEAF            0x80000000
37 #define RIGHT_IS_LEAF           0x40000000
38 #define IS_LEFT_LEAF(x)         (((x) & LEFT_IS_LEAF) != 0)
39 #define IS_RIGHT_LEAF(x)        (((x) & RIGHT_IS_LEAF) != 0)
40 #define BITNO(x)                ((x) & ~(LEFT_IS_LEAF|RIGHT_IS_LEAF))
41 #define CHECKBITS               8
42
43 struct tree {
44         int bitno;
45         struct tree *lr[2];
46 };
47
ragge
1.3
48 static struct tree *firstname;
ragge
1.2
49 int nametabsnamestrlen;
ragge
1.3
50 static struct tree *firststr;
51 int strtabsstrstrlen;
52 static char *symtab_add(char *keystruct tree **, int *, int *);
ragge
1.21
53 int lastloc = NOSEG;
ragge
1.1
54
55 #define P_BIT(key, bit) (key[bit >> 3] >> (bit & 7)) & 1
56 #define getree() permalloc(sizeof(struct tree))
57
ragge
1.3
58 char *
59 addname(char *key)      
60 {
61         return symtab_add(key, &firstname, &nametabs, &namestrlen);
62 }
63
64 char *
65 addstring(char *key)
66 {
67         return symtab_add(key, &firststr, &strtabs, &strstrlen);
68 }
69
ragge
1.1
70 /*
71  * Add a name to the name stack (if its non-existing),
72  * return its address.
73  * This is a simple patricia implementation.
74  */
75 char *
ragge
1.3
76 symtab_add(char *keystruct tree **firstint *tabsint *stlen)
ragge
1.1
77 {
78         struct tree *w, *new, *last;
79         int cixbitfbitsvbitixbitnolen;
80         char *m, *k, *sm;
81
82         /* Count full string length */
83         for (k = keylen = 0; *kk++, len++)
84                 ;
85         
ragge
1.3
86         switch (*tabs) {
ragge
1.1
87         case 0:
ragge
1.3
88                 *first = (struct tree *)newstring(keylen);
89                 *stlen += (len + 1);
90                 (*tabs)++;
91                 return (char *)*first;
ragge
1.1
92
93         case 1:
ragge
1.3
94                 m = (char *)*first;
ragge
1.13
95                 svbit = 0/* XXX why? */
ragge
1.1
96                 break;
97
98         default:
ragge
1.3
99                 w = *first;
ragge
1.1
100                 bitno = len * CHECKBITS;
101                 for (;;) {
102                         bit = BITNO(w->bitno);
103                         fbit = bit > bitno ? 0 : P_BIT(keybit);
104                         svbit = fbit ? IS_RIGHT_LEAF(w->bitno) :
105                             IS_LEFT_LEAF(w->bitno);
106                         w = w->lr[fbit];
107                         if (svbit) {
108                                 m = (char *)w;
109                                 break;
110                         }
111                 }
112         }
113
114         sm = m;
115         k = key;
116
117         /* Check for correct string and return */
118         for (cix = 0; *m && *k && *m == *km++, k++, cix += CHECKBITS)
119                 ;
120         if (*m == 0 && *k == 0)
121                 return sm;
122
123         ix = *m ^ *k;
124         while ((ix & 1) == 0)
125                 ix >>= 1cix++;
126
127         /* Create new node */
128         new = getree();
129         bit = P_BIT(keycix);
130         new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
131         new->lr[bit] = (struct tree *)newstring(keylen);
ragge
1.3
132         *stlen += (len + 1);
ragge
1.1
133
ragge
1.3
134         if ((*tabs)++ == 1) {
135                 new->lr[!bit] = *first;
ragge
1.1
136                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
ragge
1.3
137                 *first = new;
ragge
1.1
138                 return (char *)new->lr[bit];
139         }
140
141
ragge
1.3
142         w = *first;
ragge
1.1
143         last = NULL;
144         for (;;) {
145                 fbit = w->bitno;
146                 bitno = BITNO(w->bitno);
147                 if (bitno == cix)
148                         cerror("bitno == cix");
149                 if (bitno > cix)
150                         break;
151                 svbit = P_BIT(keybitno);
152                 last = w;
153                 w = w->lr[svbit];
154                 if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF))
155                         break;
156         }
157
158         new->lr[!bit] = w;
159         if (last == NULL) {
ragge
1.3
160                 *first = new;
ragge
1.1
161         } else {
162                 last->lr[svbit] = new;
163                 last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
164         }
165         if (bitno < cix)
166                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
167         return (char *)new->lr[bit];
ragge
1.4
168 }
169
ragge
1.5
170 static struct tree *sympole[NSTYPES];
ragge
1.8
171 static struct symtab *tmpsyms[NSTYPES];
ragge
1.5
172 int numsyms[NSTYPES];
ragge
1.4
173
174 /*
175  * Inserts a symbol into the symbol tree.
176  * Returns a struct symtab.
177  */
178 struct symtab *
gmcgarry
1.17
179 lookup(char *keyint stype)
ragge
1.4
180 {
181         struct symtab *sym;
182         struct tree *w, *new, *last;
stefan
1.16
183         int cixbitfbitsvbitbitno;
ragge
1.8
184         int typeuselvl;
stefan
1.16
185         intptr_t ixmatchcode = (intptr_t)key;
ragge
1.4
186
gmcgarry
1.17
187         type = stype & SMASK;
ragge
1.8
188         uselvl = (blevel > 0 && type != SSTRING);
189
190         /*
191          * The local symbols are kept in a simple linked list.
192          * Check this list first.
193          */
ragge
1.9
194         if (blevel > 0)
195                 for (sym = tmpsyms[type]; symsym = sym->snext)
196                         if (sym->sname == key)
197                                 return sym;
ragge
1.4
198
ragge
1.5
199         switch (numsyms[type]) {
ragge
1.4
200         case 0:
gmcgarry
1.17
201                 if (stype & SNOCREAT)
ragge
1.6
202                         return NULL;
ragge
1.8
203                 if (uselvl) {
gmcgarry
1.17
204                         sym = getsymtab(keystype|STEMP);
ragge
1.8
205                         sym->snext = tmpsyms[type];
206                         tmpsyms[type] = sym;
207                         return sym;
208                 }
gmcgarry
1.17
209                 sympole[type] = (struct tree *)getsymtab(keystype);
ragge
1.5
210                 numsyms[type]++;
211                 return (struct symtab *)sympole[type];
ragge
1.4
212
213         case 1:
ragge
1.5
214                 w = (struct tree *)sympole[type];
ragge
1.13
215                 svbit = 0/* XXX why? */
ragge
1.4
216                 break;
217
218         default:
ragge
1.5
219                 w = sympole[type];
ragge
1.4
220                 for (;;) {
221                         bit = BITNO(w->bitno);
222                         fbit = (code >> bit) & 1;
223                         svbit = fbit ? IS_RIGHT_LEAF(w->bitno) :
224                             IS_LEFT_LEAF(w->bitno);
225                         w = w->lr[fbit];
226                         if (svbit)
227                                 break;
228                 }
229         }
230
231         sym = (struct symtab *)w;
stefan
1.16
232         match = (intptr_t)sym->sname;
ragge
1.4
233
234         ix = code ^ match;
235         if (ix == 0)
236                 return sym;
gmcgarry
1.17
237         else if (stype & SNOCREAT)
ragge
1.6
238                 return NULL;
239
ragge
1.9
240 #ifdef PCC_DEBUG
241         if (ddebug)
242                 printf("        adding %s as %s at level %d\n",
243                     keyuselvl ? "temp" : "perm"blevel);
244 #endif
245
ragge
1.6
246         /*
ragge
1.8
247          * Insert into the linked list, if feasible.
248          */
249         if (uselvl) {
gmcgarry
1.17
250                 sym = getsymtab(keystype|STEMP);
ragge
1.8
251                 sym->snext = tmpsyms[type];
252                 tmpsyms[type] = sym;
253                 return sym;
254         }
255
256         /*
ragge
1.6
257          * Need a new node. If type is SNORMAL and inside a function
258          * the node must be allocated as permanent anyway.
259          * This could be optimized by adding a remove routine, but it
260          * may be more trouble than it is worth.
261          */
gmcgarry
1.17
262         if (stype == (STEMP|SNORMAL))
263                 stype = SNORMAL;
ragge
1.6
264
ragge
1.4
265         for (cix = 0; (ix & 1) == 0ix >>= 1cix++)
266                 ;
267
gmcgarry
1.17
268         new = stype & STEMP ? tmpalloc(sizeof(struct tree)) :
ragge
1.6
269             permalloc(sizeof(struct tree));
ragge
1.4
270         bit = (code >> cix) & 1;
271         new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
gmcgarry
1.17
272         new->lr[bit] = (struct tree *)getsymtab(keystype);
ragge
1.5
273         if (numsyms[type]++ == 1) {
274                 new->lr[!bit] = sympole[type];
ragge
1.4
275                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
ragge
1.5
276                 sympole[type] = new;
ragge
1.4
277                 return (struct symtab *)new->lr[bit];
278         }
279
280
ragge
1.5
281         w = sympole[type];
ragge
1.4
282         last = NULL;
283         for (;;) {
284                 fbit = w->bitno;
285                 bitno = BITNO(w->bitno);
286                 if (bitno == cix)
287                         cerror("bitno == cix");
288                 if (bitno > cix)
289                         break;
290                 svbit = (code >> bitno) & 1;
291                 last = w;
292                 w = w->lr[svbit];
293                 if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF))
294                         break;
295         }
296
297         new->lr[!bit] = w;
298         if (last == NULL) {
ragge
1.5
299                 sympole[type] = new;
ragge
1.4
300         } else {
301                 last->lr[svbit] = new;
302                 last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF);
303         }
304         if (bitno < cix)
305                 new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF);
306         return (struct symtab *)new->lr[bit];
ragge
1.5
307 }
308
309 void
310 symclear(int level)
311 {
ragge
1.12
312         struct symtab *s;
ragge
1.8
313         int i;
ragge
1.6
314
ragge
1.9
315 #ifdef PCC_DEBUG
316         if (ddebug)
317                 printf("symclear(%d)\n"level);
318 #endif
ragge
1.5
319         if (level < 1) {
ragge
1.12
320                 for (i = 0i < NSTYPESi++) {
321                         s = tmpsyms[i];
ragge
1.8
322                         tmpsyms[i] = 0;
ragge
1.12
323                         if (i != SLBLNAME)
324                                 continue;
325                         while (s != NULL) {
326                                 if (s->soffset < 0)
327                                         uerror("label '%s' undefined",s->sname);
328                                 s = s->snext;
329                         }
330                 }
ragge
1.11
331         } else {
ragge
1.10
332                 for (i = 0i < NSTYPESi++) {
333                         if (i == SLBLNAME)
334                                 continue/* function scope */
ragge
1.11
335                         while (tmpsyms[i] != NULL &&
336                             tmpsyms[i]->slevel > level) {
ragge
1.8
337                                 tmpsyms[i] = tmpsyms[i]->snext;
ragge
1.11
338                         }
ragge
1.10
339                 }
ragge
1.11
340         }
ragge
1.6
341 }
342
343 struct symtab *
344 hide(struct symtab *sym)
345 {
ragge
1.8
346         struct symtab *new;
ragge
1.15
347         int typ = sym->sflags & SMASK;
ragge
1.6
348
ragge
1.15
349         new = getsymtab(sym->snametyp|STEMP);
350         new->snext = tmpsyms[typ];
351         tmpsyms[typ] = new;
gmcgarry
1.17
352
ragge
1.19
353         warner(Wshadowsym->snamesym->slevel ? "local" : "global");
gmcgarry
1.18
354
ragge
1.6
355 #ifdef PCC_DEBUG
356         if (ddebug)
ragge
1.8
357                 printf("\t%s hidden at level %d (%p -> %p)\n",
358                     sym->snameblevelsymnew);
ragge
1.6
359 #endif
ragge
1.8
360         return new;
ragge
1.1
361 }
ragge
1.20
362
363 /*
364  * Extract correct segment for the specified symbol and call
365  * target routines to print it out.
366  * If symtab entry is specified, output alignment as well.
367  */
368 void
369 locctr(int segstruct symtab *sp)
370 {
371         struct attr *ga;
372
373         if (seg == NOSEG) {
374                 ;
375         } else if (sp == NULL) {
376                 if (lastloc != seg)
377                         setseg(segNULL);
378         } else if ((ga = attr_find(sp->sapGCC_ATYP_SECTION)) != NULL) {
379                 setseg(NMSEGga->sarg(0));
380                 seg = NOSEG;
381         } else {
382                 if (seg == DATA) {
383                         if (ISCON(cqual(sp->stypesp->squal)))
384                                 seg = RDATA;
385                         else if (sp->sclass == STATIC)
386                                 seg = LDATA;
387                 }
388                 if (kflag) {
389                         if (seg == DATAseg = PICDATA;
390                         if (seg == RDATAseg = PICRDATA;
391                         if (seg == LDATAseg = PICLDATA;
392                 } else if (sp->sflags & STLS) {
393                         if (seg == DATA || seg == LDATA)
394                                 seg = TLSDATA;
395                         if (seg == UDATAseg = TLSUDATA;
396                 }
397                 if (lastloc != seg)
398                         setseg(segNULL);
399         }
400         lastloc = seg;
401
402         /* setup alignment */
403 #ifndef ALFTN
404 #define ALFTN   ALINT
405 #endif
406         if (sp) {
407                 int al;
408
409                 if (ISFTN(sp->stype)) {
410                         al = ALFTN;
411                 } else
412                         al = talign(sp->stypesp->sap);
413                 defalign(al);
414                 symdirec(sp);
415         }
416 }
417
418 #ifndef MYALIGN
419 void
420 defalign(int al)
421 {
422         printf("\t.align %d\n"al/ALCHAR);
423 }
424 #endif
425
426 #ifndef MYDIREC
427 /*
428  * Directives given as attributes to symbols.
429  */
430 void
431 symdirec(struct symtab *sp)
432 {
433         struct attr *ga;
434         char *name;
435
436         if ((name = sp->soname) == NULL)
437                 name = exname(sp->sname);
438         if ((ga = attr_find(sp->sapGCC_ATYP_WEAK)) != NULL)
439                 printf("\t.weak %s\n"name);
440         if ((ga = attr_find(sp->sapGCC_ATYP_VISIBILITY)) &&
441             strcmp(ga->sarg(0), "default"))
442                 printf("\t.%s %s\n"ga->sarg(0), name);
443         if ((ga = attr_find(sp->sapGCC_ATYP_ALIASWEAK))) {
444                 printf("\t.weak %s\n"ga->sarg(0));
445                 printf("\t.set %s,%s\n"ga->sarg(0), name);
446         }
447 }
448 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-07-10 21:30 +0200