OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [Symbol.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2012-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
char *prefix;
29
extern int nparms;
30
extern bool isRegister;
31
 
32
SYM *SYM::GetPtr(int n)
33
{
34
  if (n==0)
35
    return nullptr;
36
  if (n > 32767)
37
     return nullptr;
38
  return (SYM *)&compiler.symbolTable[n];
39
}
40
 
41
SYM *SYM::GetNextPtr()
42
{
43
  if (next==0)
44
     return nullptr;
45
  if (next > 32767)
46
     return nullptr;
47
  return &compiler.symbolTable[next];
48
}
49
 
50
SYM *SYM::GetParentPtr()
51
{
52
        if (parent==0)
53
           return nullptr;
54
  if (parent > 32767)
55
     return nullptr;
56
   return &compiler.symbolTable[parent];
57
};
58
 
59
int SYM::GetIndex()
60
{
61
  if (this==nullptr)
62
     return 0;
63
  return this - &compiler.symbolTable[0];
64
};
65
 
66
uint8_t hashadd(char *nm)
67
{
68
        uint8_t hsh;
69
 
70
        for(hsh=0;*nm;nm++)
71
                hsh += *nm;
72
        return hsh;
73
}
74
 
75
SYM *search2(std::string na,TABLE *tbl,TypeArray *typearray)
76
{
77
        SYM *thead;
78
        TypeArray *ta;
79
 
80
        if (na=="" || tbl==nullptr)
81
                return nullptr;
82
//      printf("Enter search2\r\n");
83
        if (tbl==&gsyms[0])
84
                thead = compiler.symbolTable[0].GetPtr(hashadd((char *)na.c_str()));
85
        else
86
                thead = &compiler.symbolTable[tbl->GetHead()];
87
        while( thead != NULL) {
88
                if (thead->name->length() != 0) {
89
                  /*
90
                        if (prefix)
91
                                strncpy(namebuf,prefix,sizeof(namebuf)-1);
92
                        else
93
                                namebuf[0]='\0';
94
                        strncat(namebuf,thead->name,sizeof(namebuf)-1);
95
                        */
96
                        if(thead->name->compare(na)==0) {
97
                                if (typearray) {
98
                                        ta = thead->fi->GetProtoTypes();
99
                                        if (ta->IsEqual(typearray))
100
                                                break;
101
                                        if (ta)
102
                                                delete ta;
103
                                }
104
                                else
105
                                        break;
106
                        }
107
                }
108
    thead = thead->GetNextPtr();
109
    }
110
//      printf("Leave search2\r\n");
111
    return (thead);
112
}
113
 
114
SYM *search(std::string na,TABLE *tbl)
115
{
116
        return search2(na,tbl,nullptr);
117
}
118
 
119
// first look in the current compound statement for the symbol,
120
// Next look in progressively more outer compound statements
121
// Next look in the local symbol table for the function
122
// Finally look in the global symbol table.
123
//
124
SYM *gsearch2(std::string na, __int16 rettype, TypeArray *typearray, bool exact)
125
{
126
        SYM *sp;
127
        Statement *st;
128
        SYM *p;
129
 
130
        dfs.printf("\n<gsearch2> for: |%s|\n", (char *)na.c_str());
131
        prefix = nullptr;
132
        sp = nullptr;
133
        // There might not be a current statement if global declarations are
134
        // being processed.
135
        if (currentStmt==NULL) {
136
          dfs.printf("Stmt=null, looking in global table\n");
137
                if (gsyms[0].Find(na,rettype,typearray,exact)) {
138
                        sp = TABLE::match[TABLE::matchno-1];
139
                        dfs.printf("Found in global symbol table\n");
140
                        dfs.puts("</gsearch2>\n");
141
                        return sp;
142
                }
143
                dfs.puts("</gsearch2>\n");
144
                return nullptr;
145
        }
146
        else {
147
    dfs.printf("Looking in statement table\n");
148
                if (currentStmt->ssyms.Find(na,rettype,typearray,exact)) {
149
                        sp = TABLE::match[TABLE::matchno-1];
150
        dfs.printf("Found as an auto var\n");
151
                        dfs.puts("</gsearch2>\n");
152
                        return sp;
153
                }
154
                st = currentStmt->outer;
155
                while (st) {
156
    dfs.printf("Looking in outer statement table\n");
157
                        if (st->ssyms.Find(na,rettype,typearray,exact)) {
158
                                sp = TABLE::match[TABLE::matchno-1];
159
        dfs.printf("Found as an auto var\n");
160
                        dfs.puts("</gsearch2>\n");
161
                                return (sp);
162
                        }
163
                        st = st->outer;
164
                }
165
                p = currentFn->sym;
166
                if (p) {
167
      dfs.printf("Looking in function's symbol table\n");
168
                if (currentFn->sym->lsyms.Find(na,rettype,typearray,exact)) {
169
                        sp = TABLE::match[TABLE::matchno-1];
170
        dfs.printf("Found in function symbol table (a label)\n");
171
                        dfs.puts("</gsearch2>\n");
172
                        return (sp);
173
                }
174
                while(p) {
175
                        dfs.printf("Searching method/class:%s|%p\n",(char *)p->name->c_str(),(char *)p);
176
                        if (p->tp) {
177
                        if (p->tp->type != bt_class) {
178
                        dfs.printf("Looking at params %p\n",(char *)&p->fi->params);
179
                        if (p->fi->params.Find(na,rettype,typearray,exact)) {
180
                                sp = TABLE::match[TABLE::matchno-1];
181
                dfs.printf("Found as parameter\n");
182
                                dfs.puts("</gsearch2>\n");
183
                                return (sp);
184
                        }
185
                  }
186
                        // Search for class member
187
                        dfs.printf("Looking at class members %p\n",(char *)&p->tp->lst);
188
                        if (p->tp->type == bt_class) {
189
                          SYM *tab;
190
                          int nn;
191
                                if (p->tp->lst.Find(na,rettype,typearray,exact)) {
192
                                        sp = TABLE::match[TABLE::matchno-1];
193
                dfs.printf("Found in class\n");
194
                                dfs.puts("</gsearch2>\n");
195
                                        return (sp);
196
                                }
197
                                dfs.printf("Base=%d",p->tp->lst.base);
198
                                tab = p->GetPtr(p->tp->lst.base);
199
                                dfs.printf("Base=%p",(char *)tab);
200
                                if (tab) {
201
                                  dfs.puts("Has a base class");
202
                                  if (tab->tp) {
203
                                dfs.printf("Looking at base class members:%p\n",(char *)tab);
204
                                        nn = tab->tp->lst.FindRising(na);
205
                                        if (nn > 0) {
206
                        dfs.printf("Found in base class\n");
207
                                          if (exact) {
208
                                          //sp = sp->FindRisingMatch();
209
                                            sp = Function::FindExactMatch(TABLE::matchno, na, bt_long, typearray)->sym;
210
                                            if (sp) {
211
                                        dfs.puts("</gsearch2>\n");
212
                                              return (sp);
213
                                      }
214
                                          }
215
                                          else {
216
                                        sp = TABLE::match[0];
217
                                dfs.puts("</gsearch2>\n");
218
                                        return (sp);
219
                                      }
220
                                    }
221
                                }
222
                          }
223
                          }
224
                        }
225
                        p = p->GetParentPtr();
226
                }
227
        }
228
                // Finally, look in the global symbol table
229
                dfs.printf("Looking at global symbols\n");
230
                if (gsyms[0].Find(na,rettype,typearray,exact)) {
231
                        sp = TABLE::match[TABLE::matchno-1];
232
                        dfs.printf("Found in global symbol table\n");
233
                        dfs.puts("</gsearch2>\n");
234
                        return (sp);
235
                }
236
        }
237
 
238
        dfs.puts("</gsearch2>\n");
239
  return (sp);
240
}
241
 
242
// A wrapper for gsearch2() when we only care about finding any match.
243
 
244
SYM *gsearch(std::string name)
245
{
246
        return (gsearch2(name, bt_long, nullptr, false));
247
}
248
 
249
 
250
// Create a copy of a symbol, used when creating derived classes from base
251
// classes. The type is copyied and extended by a derived class.
252
 
253
SYM *SYM::Copy(SYM *src)
254
{
255
        SYM *dst = nullptr;
256
 
257
  dfs.printf("Enter SYM::Copy\n");
258
        if (src) {
259
                dst = allocSYM();
260
                dfs.printf("A");
261
                memcpy(dst, src, sizeof(SYM));
262
//              dst->tp = TYP::Copy(src->tp);
263
//              dst->name = src->name;
264
//              dst->shortname = src->shortname;
265
                dst->SetNext(0);
266
                if (src->fi) {
267
                        dst->fi = allocFunction(src->id);
268
                        memcpy(dst->fi, src->fi, sizeof(Function));
269
                        dst->fi->sym = dst;
270
                        dst->fi->params.SetOwner(src->id);
271
                        dst->fi->proto.SetOwner(src->id);
272
                }
273
  }
274
  dfs.printf("Leave SYM::Copy\n");
275
        return (dst);
276
}
277
 
278
SYM *SYM::Find(std::string nme)
279
{
280
        SYM *sp;
281
 
282
//      printf("Enter Find(char *)\r\n");
283
        sp = tp->lst.Find(nme,false);
284
        if (sp==nullptr) {
285
                if (parent) {
286
                        sp = GetPtr(parent)->Find(nme);
287
                }
288
        }
289
//      printf("Leave Find(char *):%p\r\n",sp);
290
        return (sp);
291
}
292
 
293
int SYM::FindNextExactMatch(int startpos, TypeArray * tb)
294
{
295
        SYM *sp1;
296
        int nn;
297
        TypeArray *ta;
298
 
299
        sp1 = nullptr;
300
        for (nn = startpos; nn < TABLE::matchno; nn++) {
301
                sp1 = TABLE::match[nn];
302
                if (fi) {
303
                        ta = sp1->fi->GetProtoTypes();
304
                        if (ta->IsEqual(tb)) {
305
                                delete ta;
306
                                return (nn);
307
                        }
308
                        delete ta;
309
                }
310
        }
311
        return (-1);
312
}
313
 
314
 
315
SYM *SYM::FindRisingMatch(bool ignore)
316
{
317
        int nn;
318
        int em;
319
        int iter;
320
        SYM *s = this;
321
        std::string nme;
322
        TypeArray *ta = nullptr;
323
 
324
        nme = *name;
325
        if (fi)
326
                ta = fi->GetProtoTypes();
327
        dfs.printf("<FindRisingMatch>%s type %d ", (char *)name->c_str(), tp->type);
328
        if (GetParentPtr() != nullptr)
329
                nn = GetParentPtr()->tp->lst.FindRising(nme);
330
        else
331
                nn = 1;
332
        //  nn = tp->lst.FindRising(nme);
333
        iter = 0;
334
        if (nn) {
335
                dfs.puts("Found method:");
336
                for (iter = 0; true; iter = em + 1) {
337
                        em = FindNextExactMatch(iter, ta);
338
                        if (em < 0)
339
                                break;
340
                        s = TABLE::match[em];
341
                        if (!ignore || s->GetParentPtr() != GetParentPtr()) { // ignore entry here
342
                                dfs.puts("Found in a base class:");
343
                                break;
344
                        }
345
                        s = nullptr;
346
                }
347
        }
348
        if (ta)
349
                delete ta;
350
        dfs.printf("</FindRisingMatch>\n");
351
        return (s);
352
}
353
 
354
 
355
// Convert a type number to a character string
356
// These will always be four characters.
357
 
358
std::string *TypenoToChars(int typeno)
359
{
360
        const char *alphabet =
361
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456";
362
        char c[8];
363
        std::string *str;
364
 
365
  dfs.puts("<TypenoToChars>");
366
  str = new std::string();
367
  dfs.putch('A');
368
        c[0] = alphabet[typeno & 31];
369
  dfs.putch('B');
370
        c[1] = alphabet[(typeno>>5) & 31];
371
  dfs.putch('C');
372
        c[2] = alphabet[(typeno>>10) & 31];
373
  c[3] = alphabet[(typeno>>15) & 31];
374
  c[4] = '\0';
375
  c[5] = '\0';
376
  c[6] = '\0';
377
  c[7] = '\0';
378
  dfs.puts("D:");
379
        str->append(c);
380
        dfs.printf("%s",(char *)str->c_str());
381
  dfs.puts("</TypenoToChars>");
382
        return str;
383
}
384
 
385
// Get the mangled name for the function
386
//
387
std::string *SYM::GetNameHash()
388
{
389
        std::string *nh;
390
  SYM *sp;
391
  int nn;
392
 
393
  dfs.puts("<GetNameHash>");
394
  dfs.printf("tp:%p",(char *)tp);
395
//  if (tp==(TYP *)0x500000005LL) {
396
//    nh = new std::string("TAA");
397
//    return nh;
398
//  }
399
        nh = TypenoToChars(tp->typeno);
400
  dfs.putch('A');
401
  sp = GetParentPtr();
402
  if (sp) {
403
     nh->append(*sp->GetNameHash());
404
           sp = GetPtr(sp->tp->lst.base);
405
     dfs.putch('B');
406
         for (nn = 0; sp && nn < 200; nn++) {
407
           dfs.putch('.');
408
           nh->append(*sp->GetNameHash());
409
       sp = GetPtr(sp->tp->lst.base);
410
         }
411
           if (nn >= 200) {
412
             error(ERR_CIRCULAR_LIST);
413
    }
414
        }
415
/*
416
        if (parent) {
417
          sp = GetPtr(parent);
418
                nh += sp->GetNameHash();
419
        }
420
*/
421
  dfs.puts("</GetNameHash>\n");
422
        return nh;
423
}
424
 
425
// Build a function signature string including
426
// the return type, base classes, and any parameters.
427
 
428
std::string *SYM::BuildSignature(int opt)
429
{
430
        std::string *str;
431
        std::string *nh;
432
 
433
        dfs.printf("<BuildSignature>");
434
        if (this == nullptr) {
435
                str = new std::string("");
436
                str->append(*name);
437
                dfs.printf(":%s</BuildSignature>", (char *)str->c_str());
438
                return (str);
439
        }
440
        if (mangledNames) {
441
                str = new std::string("_Z");            // 'C' likes this
442
                dfs.printf("A");
443
                nh = GetNameHash();
444
                dfs.printf("B");
445
                str->append(*nh);
446
                dfs.printf("C");
447
                delete nh;
448
                dfs.printf("D");
449
                if (name > (std::string *)0x15)
450
                        str->append(*name);
451
                if (opt) {
452
                        dfs.printf("E");
453
                        str->append(*fi->GetParameterTypes()->BuildSignature());
454
                }
455
                else {
456
                        dfs.printf("F");
457
                        str->append(*fi->GetProtoTypes()->BuildSignature());
458
                }
459
        }
460
        else {
461
                str = new std::string("");
462
                str->append(*name);
463
        }
464
        dfs.printf(":%s</BuildSignature>", (char *)str->c_str());
465
        return str;
466
}
467
 
468
 
469
// Called during declaration parsing.
470
 
471
// Auto variables are referenced negative to the base pointer
472
// Structs need to be aligned on the boundary of the largest
473
// struct element. If a struct is all chars this will be 2.
474
// If a struct contains a pointer this will be 8. It has to
475
// be the worst case alignment.
476
 
477
void SYM::SetStorageOffset(TYP *head, int nbytes, int al, int ilc, int ztype)
478
{
479
        // Set the struct member storage offset.
480
        if (al == sc_static || al == sc_thread) {
481
                value.i = nextlabel++;
482
        }
483
        else if (ztype == bt_union) {
484
                value.i = ilc;// + parentBytes;
485
        }
486
        else if (al != sc_auto) {
487
                value.i = ilc + nbytes;// + parentBytes;
488
        }
489
        else {
490
                value.i = -(ilc + nbytes + head->roundSize());// + parentBytes);
491
        }
492
}
493
 
494
 
495
// Increase the storage allocation by the type size.
496
 
497
int SYM::AdjustNbytes(int nbytes, int al, int ztype)
498
{
499
        if (ztype == bt_union)
500
                nbytes = imax(nbytes, tp->roundSize());
501
        else if (al != sc_external) {
502
                // If a pointer to a function is defined in a struct.
503
                if (isStructDecl) {
504
                        if (tp->type == bt_func) {
505
                                nbytes += 8;
506
                        }
507
                        else if (tp->type != bt_ifunc) {
508
                                nbytes += tp->roundSize();
509
                        }
510
                }
511
                else {
512
                        nbytes += tp->roundSize();
513
                }
514
        }
515
        return (nbytes);
516
}
517
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.