1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
|
/*-------------------------------------------------------------------------
SDCCsymt.h - Header file for Symbols table related structures and MACRO's.
Copyright (C) 1998 Sandeep Dutta . sandeep.dutta@usa.net
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-------------------------------------------------------------------------*/
#ifndef SDCCSYMT_H
#define SDCCSYMT_H
#define MAX_NEST_LEVEL 256
#define SDCC_SYMNAME_MAX 64
#define SDCC_NAME_MAX 3*SDCC_SYMNAME_MAX // big enough for _<func>_<var>_etc
#include "SDCChasht.h"
#include "SDCCglobl.h"
#include "dbuf.h"
#define INTNO_MAX 255 /* maximum allowed interrupt number */
#define INTNO_TRAP INTNO_MAX
#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */
#define BITVAR_PAD -1
enum
{
TYPEOF_INT = 1,
TYPEOF_SHORT,
TYPEOF_BOOL,
TYPEOF_CHAR,
TYPEOF_LONG,
TYPEOF_LONGLONG,
TYPEOF_FLOAT,
TYPEOF_FIXED16X16,
TYPEOF_BIT,
TYPEOF_BITFIELD,
TYPEOF_SBIT,
TYPEOF_SFR,
TYPEOF_VOID,
TYPEOF_STRUCT,
TYPEOF_ARRAY,
TYPEOF_FUNCTION,
TYPEOF_POINTER,
TYPEOF_FPOINTER,
TYPEOF_CPOINTER,
TYPEOF_GPOINTER,
TYPEOF_PPOINTER,
TYPEOF_IPOINTER,
TYPEOF_EEPPOINTER
};
// values for first byte (or 3 most significant bits) of generic pointer.
#if 0
#define GPTYPE_FAR 0x00
#define GPTYPE_NEAR 0x40
#define GPTYPE_XSTACK 0x60
#define GPTYPE_CODE 0x80
#else
#define GPTYPE_FAR (port->gp_tags.tag_far)
#define GPTYPE_NEAR (port->gp_tags.tag_near)
#define GPTYPE_XSTACK (port->gp_tags.tag_xstack)
#define GPTYPE_CODE (port->gp_tags.tag_code)
#endif
#define HASHTAB_SIZE 256
/* hash table bucket */
typedef struct bucket
{
void *sym; /* pointer to the object */
char name[SDCC_NAME_MAX + 1]; /* name of this symbol */
long level; /* nest level for this symbol */
int block; /* belongs to which block */
struct bucket *prev; /* ptr 2 previous bucket */
struct bucket *next; /* ptr 2 next bucket */
}
bucket;
typedef struct structdef
{
char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */
long level; /* Nesting level */
int block; /* belongs to which block */
struct symbol *fields; /* pointer to fields */
unsigned size; /* sizeof the table in bytes */
int type; /* STRUCT or UNION */
bool b_flexArrayMember; /* has got a flexible array member,
only needed for syntax checks */
struct symbol *tagsym; /* tag symbol (NULL if no tag) */
}
structdef;
/* noun definitions */
typedef enum
{
V_INT = 1,
V_FLOAT,
V_FIXED16X16,
V_BOOL,
V_CHAR,
V_VOID,
V_STRUCT,
V_LABEL,
V_BIT,
V_BITFIELD,
V_BBITFIELD,
V_SBIT,
V_DOUBLE
}
NOUN;
/* storage class */
typedef enum
{
S_FIXED = 0,
S_AUTO,
S_REGISTER,
S_SFR,
S_SBIT,
S_CODE,
S_XDATA,
S_DATA,
S_IDATA,
S_PDATA,
S_LITERAL,
S_STACK,
S_XSTACK,
S_BIT,
S_EEPROM
}
STORAGE_CLASS;
#define TYPE_TARGET_CHAR TYPE_BYTE
#define TYPE_TARGET_INT TYPE_WORD
#define TYPE_TARGET_LONG TYPE_DWORD
#define TYPE_TARGET_UCHAR TYPE_UBYTE
#define TYPE_TARGET_UINT TYPE_UWORD
#define TYPE_TARGET_ULONG TYPE_UDWORD
#define TYPE_TARGET_LONGLONG TYPE_QWORD
#define TYPE_TARGET_ULONGLONG TYPE_UQWORD
/* specifier is the last in the type-chain */
typedef struct specifier
{
NOUN noun; /* CHAR INT STRUCTURE LABEL */
STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */
struct memmap *oclass; /* output storage class */
unsigned b_long:1; /* 1=long */
unsigned b_longlong:1; /* 1=long long */
unsigned b_short:1; /* 1=short int */
unsigned b_unsigned:1; /* 1=unsigned, 0=signed */
unsigned b_signed:1; /* just for sanity checks only*/
bool b_implicit_sign:1; /* signedness not explicitly specified - needed to keep char a separate type from signed char and unsigned char. */
unsigned b_static:1; /* 1=static keyword found */
unsigned b_extern:1; /* 1=extern found */
unsigned b_inline:1; /* inline function requested */
unsigned b_noreturn:1; /* promised not to return */
unsigned b_alignas:1; /* alignment */
unsigned b_absadr:1; /* absolute address specfied */
unsigned b_volatile:1; /* is marked as volatile */
unsigned b_const:1; /* is a constant */
unsigned b_restrict:1; /* is restricted */
struct symbol *addrspace; /* is in named address space */
unsigned b_typedef:1; /* is typedefed */
unsigned b_isregparm:1; /* is the first parameter */
unsigned b_isenum:1; /* is an enumerated type */
unsigned b_bitUnnamed:1; /* is an unnamed bit-field */
unsigned b_needspar:1; /* has to be a parameter */
unsigned _bitStart; /* bit start position */
unsigned _bitLength; /* bit length */
unsigned _addr; /* address of symbol */
unsigned _stack; /* stack offset for stacked v */
int argreg; /* reg no for regparm */
union
{ /* Values if constant or enum */
TYPE_TARGET_INT v_int; /* 2 bytes: int and char values */
const char *v_char; /* char character string */
const TYPE_TARGET_UINT *v_char16; /* char16_t character string */
const TYPE_TARGET_ULONG *v_char32;/* char32_t character string */
TYPE_TARGET_UINT v_uint; /* 2 bytes: unsigned int const value */
TYPE_TARGET_LONG v_long; /* 4 bytes: long constant value */
TYPE_TARGET_ULONG v_ulong; /* 4 bytes: unsigned long constant value */
TYPE_TARGET_LONGLONG v_longlong; /* 8 bytes: long long constant value */
TYPE_TARGET_ULONGLONG v_ulonglong;/* 8 bytes: unsigned long long const value */
double v_float; /* floating point constant value */
TYPE_TARGET_ULONG v_fixed16x16; /* 4 bytes: fixed point constant value */
struct symbol *v_enum; /* ptr to enum_list if enum==1 */
}
const_val;
struct structdef *v_struct; /* structure pointer */
}
specifier;
/* types of declarators */
typedef enum
{
UPOINTER = 0, /* unknown pointer used only when parsing */
POINTER, /* pointer to near data */
IPOINTER, /* pointer to upper 128 bytes */
PPOINTER, /* paged area pointer */
FPOINTER, /* pointer to far data */
CPOINTER, /* pointer to code space */
GPOINTER, /* generic pointer */
EEPPOINTER, /* pointer to eeprom */
ARRAY,
FUNCTION
}
DECLARATOR_TYPE;
typedef struct declarator
{
DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */
size_t num_elem; /* # of elems if type==array, */
/* always 0 for flexible arrays */
unsigned ptr_const:1; /* pointer is constant */
unsigned ptr_volatile:1; /* pointer is volatile */
unsigned ptr_restrict:1; /* pointer is resticted */
struct symbol *ptr_addrspace; /* pointer is in named address space */
struct sym_link *tspec; /* pointer type specifier */
}
declarator;
typedef enum
{
DECLARATOR = 1,
SPECIFIER
} SYM_LINK_CLASS;
#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOWN")
typedef struct sym_link
{
SYM_LINK_CLASS xclass; /* DECLARATOR or SPECIFIER */
unsigned tdef:1; /* current link created by */
/* typedef if this flag is set */
union
{
specifier s; /* if CLASS == SPECIFIER */
declarator d; /* if CLASS == DECLARATOR */
} select;
/* function attributes */
struct
{
struct value *args; /* the defined arguments */
unsigned hasVargs:1; /* functions has varargs */
unsigned calleeSaves:1; /* functions uses callee save */
unsigned hasbody:1; /* function body defined */
unsigned hasFcall:1; /* does it call other functions */
unsigned reent:1; /* function is reentrant */
unsigned naked:1; /* naked function */
unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */
unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */
unsigned nonbanked:1; /* function has the nonbanked attribute */
unsigned banked:1; /* function has the banked attribute */
unsigned critical:1; /* critical function */
unsigned intrtn:1; /* this is an interrupt routine */
unsigned rbank:1; /* seperate register bank */
unsigned inlinereq:1; /* inlining requested */
unsigned noreturn:1; /* promised not to return */
unsigned smallc:1; /* Parameters on stack are passed in reverse order */
unsigned z88dk_fastcall:1; /* For the z80-related ports: Function has a single paramter of at most 32 bits that is passed in dehl */
unsigned z88dk_callee:1; /* Stack pointer adjustment for parameters passed on the stack is done by the callee */
unsigned z88dk_shortcall:1; /* Short call available via rst (see values later) (Z80 only) */
unsigned z88dk_has_params_offset:1; /* Has a parameter offset (Z80 only) */
unsigned intno; /* Number of interrupt for interrupt service routine */
short regbank; /* register bank 2b used */
unsigned builtin; /* is a builtin function */
unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */
unsigned overlay; /* force parameters & locals into overlay segment */
unsigned hasStackParms; /* function has parameters on stack */
bool preserved_regs[9]; /* Registers preserved by the function - may be an underestimate */
unsigned char z88dk_shortcall_rst; /* Rst for a short call */
unsigned short z88dk_shortcall_val; /* Value for a short call */
unsigned short z88dk_params_offset; /* Additional offset from for arguments */
} funcAttrs;
struct sym_link *next; /* next element on the chain */
}
sym_link;
typedef struct symbol
{
char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */
char rname[SDCC_NAME_MAX + 1]; /* internal name */
long level; /* declaration lev,fld offset */
short block; /* sequential block # of definition */
int seqPoint; /* sequence point defined or, if unbound, used */
int key;
unsigned flexArrayLength; /* if the symbol specifies a struct
with a "flexible array member", then the additional length in bytes for
the "fam" is stored here. Because the length can be different from symbol
to symbol AND v_struct isn't copied in copyLinkChain(), it's located here
in the symbol and not in v_struct or the declarator */
unsigned implicit:1; /* implicit flag */
unsigned undefined:1; /* undefined variable */
unsigned infertype:1; /* type should be inferred from first assign */
unsigned _isparm:1; /* is a parameter */
unsigned ismyparm:1; /* is parameter of the function being generated */
unsigned isitmp:1; /* is an intermediate temp */
unsigned islbl:1; /* is a temporary label */
unsigned isref:1; /* has been referenced */
unsigned isind:1; /* is an induction variable */
unsigned isinvariant:1; /* is a loop invariant */
unsigned cdef:1; /* compiler defined symbol */
unsigned addrtaken:1; /* address of the symbol was taken */
unsigned isreqv:1; /* is the register equivalent of a symbol */
unsigned udChked:1; /* use def checking has been already done */
unsigned generated:1; /* code generated (function symbols only) */
unsigned isinscope:1; /* is in scope */
/* following flags are used by the backend
for code generation and can be changed
if a better scheme for backend is thought of */
unsigned isLiveFcall:1; /* is live at or across a function call */
unsigned isspilt:1; /* has to be spilt */
unsigned spillA:1; /* spilt be register allocator */
unsigned remat:1; /* can be remateriazed */
unsigned isptr:1; /* is a pointer */
unsigned uptr:1; /* used as a pointer */
unsigned isFree:1; /* used by register allocator */
unsigned islocal:1; /* is a local variable */
unsigned blockSpil:1; /* spilt at block level */
unsigned remainSpil:1; /* spilt because not used in remainder */
unsigned stackSpil:1; /* has been spilt on temp stack location */
unsigned onStack:1; /* this symbol allocated on the stack */
unsigned iaccess:1; /* indirect access */
unsigned ruonly:1; /* used in return statement only */
unsigned spildir:1; /* spilt in direct space */
unsigned ptrreg:1; /* this symbol assigned to a ptr reg */
unsigned noSpilLoc:1; /* cannot be assigned a spil location */
bool funcDivFlagSafe:1; /* we know this function is safe to call with undocumented stm8 flag bit 6 set*/
bool funcUsesVolatile:1; /* The function accesses a volatile variable */
unsigned isstrlit; /* is a string literal and it's usage count */
unsigned accuse; /* can be left in the accumulator
On the Z80 accuse is divided into
ACCUSE_A and ACCUSE_HL as the idea
is quite similar.
*/
unsigned dptr; /* 8051 variants with multiple DPTRS
currently implemented in DS390 only
*/
int allocreq; /* allocation is required for this variable */
int stack; /* offset on stack */
int xstack; /* offset on xternal stack */
short nRegs; /* number of registers required */
short regType; /* type of register required */
struct reg_info *regs[8]; /* can have at the most 8 registers */
struct asmop *aop; /* asmoperand for this symbol */
struct iCode *fuse; /* furthest use */
struct iCode *rematiCode; /* rematerialise with which instruction */
struct operand *reqv; /* register equivalent of a local variable */
struct symbol *prereqv; /* symbol before register equiv. substitution */
struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */
union
{
struct symbol *spillLoc; /* register spil location */
struct set *itmpStack; /* symbols spilt @ this stack location */
}
usl;
int bitVar; /* if bitVar != 0: this is a bit variable, bitVar is the size in bits */
unsigned bitUnnamed:1; /* unnamed bit variable */
unsigned offset; /* offset from top if struct */
int lineDef; /* defined line number */
char *fileDef; /* defined filename */
int lastLine; /* for functions the last line */
struct sym_link *type; /* 1st link to declarator chain */
struct sym_link *etype; /* last link to declarator chain */
struct symbol *next; /* crosslink to next symbol */
struct symbol *localof; /* local variable of which function */
struct initList *ival; /* ptr to initializer if any */
struct bitVect *defs; /* bit vector for definitions */
struct bitVect *uses; /* bit vector for uses */
struct bitVect *regsUsed; /* for functions registers used */
int liveFrom; /* live from iCode sequence number */
int liveTo; /* live to sequence number */
int used; /* no. of times this was used */
int recvSize; /* size of first argument */
struct bitVect *clashes; /* overlaps with what other symbols */
struct ast *funcTree; /* function body ast if inlined */
struct symbol *addressmod[2]; /* access functions for named address spaces */
bool for_newralloc;
}
symbol;
extern sym_link *validateLink (sym_link * l,
const char *macro, const char *args, const char select, const char *file, unsigned line);
/* Easy Access Macros */
#define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly)
#define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse)
#define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type
#define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem
#define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const
#define DCL_PTR_VOLATILE(l) validateLink(l, "DCL_PTR_VOLATILE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_volatile
#define DCL_PTR_RESTRICT(l) validateLink(l, "DCL_PTR_RESTRICT", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_restrict
#define DCL_PTR_ADDRSPACE(l) validateLink(l, "DCL_PTR_ADDRSPACE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_addrspace
#define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec
#define FUNC_DEBUG //assert(IS_FUNC(x));
#define FUNC_HASVARARGS(x) (x->funcAttrs.hasVargs)
#define IFFUNC_HASVARARGS(x) (IS_FUNC(x) && FUNC_HASVARARGS(x))
#define FUNC_ARGS(x) (x->funcAttrs.args)
#define IFFUNC_ARGS(x) (IS_FUNC(x) && FUNC_ARGS(x))
#define FUNC_HASFCALL(x) (x->funcAttrs.hasFcall)
#define IFFUNC_HASFCALL(x) (IS_FUNC(x) && FUNC_HASFCALL(x))
#define FUNC_HASBODY(x) (x->funcAttrs.hasbody)
#define IFFUNC_HASBODY(x) (IS_FUNC(x) && FUNC_HASBODY(x))
#define FUNC_CALLEESAVES(x) (x->funcAttrs.calleeSaves)
#define IFFUNC_CALLEESAVES(x) (IS_FUNC(x) && FUNC_CALLEESAVES(x))
#define FUNC_ISISR(x) (x->funcAttrs.intrtn)
#define IFFUNC_ISISR(x) (IS_FUNC(x) && FUNC_ISISR(x))
#define FUNC_INTNO(x) (x->funcAttrs.intno)
#define FUNC_REGBANK(x) (x->funcAttrs.regbank)
#define FUNC_HASSTACKPARM(x) (x->funcAttrs.hasStackParms)
#define FUNC_ISINLINE(x) (x->funcAttrs.inlinereq)
#define IFFUNC_ISINLINE(x) (IS_FUNC(x) && FUNC_ISINLINE(x))
#define FUNC_ISNORETURN(x) (x->funcAttrs.noreturn)
#define IFFUNC_ISNORETURN(x) (IS_FUNC(x) && FUNC_ISNORETURN(x))
#define FUNC_ISREENT(x) (x->funcAttrs.reent)
#define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x))
#define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs)
#define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x))
#define FUNC_ISWPARAM(x) (x->funcAttrs.wparam)
#define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x))
#define FUNC_ISNAKED(x) (x->funcAttrs.naked)
#define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x))
#define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked)
#define IFFUNC_NONBANKED(x) (IS_FUNC(x) && FUNC_NONBANKED(x))
#define FUNC_BANKED(x) (x->funcAttrs.banked)
#define IFFUNC_BANKED(x) (IS_FUNC(x) && FUNC_BANKED(x))
#define FUNC_ISCRITICAL(x) (x->funcAttrs.critical)
#define IFFUNC_ISCRITICAL(x) (IS_FUNC(x) && FUNC_ISCRITICAL(x))
#define FUNC_ISBUILTIN(x) (x->funcAttrs.builtin)
#define IFFUNC_ISBUILTIN(x) (IS_FUNC(x) && FUNC_ISBUILTIN(x))
#define FUNC_ISJAVANATIVE(x) (x->funcAttrs.javaNative)
#define IFFUNC_ISJAVANATIVE(x) (IS_FUNC(x) && FUNC_ISJAVANATIVE(x))
#define FUNC_ISOVERLAY(x) (x->funcAttrs.overlay)
#define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x))
#define FUNC_ISSMALLC(x) (x->funcAttrs.smallc)
#define IFFUNC_ISSMALLC(x) (IS_FUNC(x) && FUNC_ISSMALLC(x))
#define FUNC_ISZ88DK_FASTCALL(x) (x->funcAttrs.z88dk_fastcall)
#define IFFUNC_ISZ88DK_FASTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_FASTCALL(x))
#define FUNC_ISZ88DK_CALLEE(x) (x->funcAttrs.z88dk_callee)
#define IFFUNC_ISZ88DK_CALLEE(x) (IS_FUNC(x) && FUNC_ISZ88DK_CALLEE(x))
#define FUNC_ISZ88DK_SHORTCALL(x) (x->funcAttrs.z88dk_shortcall)
#define IFFUNC_ISZ88DK_SHORTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_SHORTCALL(x))
#define BANKED_FUNCTIONS ( options.model == MODEL_HUGE || \
( (options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \
TARGET_Z80_LIKE ) )
#define IFFUNC_ISBANKEDCALL(x) ( IS_FUNC(x) && \
( FUNC_BANKED(x) || ( BANKED_FUNCTIONS && !FUNC_NONBANKED(x) ) ) )
#define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun
#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_long
#define SPEC_LONGLONG(x) validateLink(x, "SPEC_LONGLONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_longlong
#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_short
#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_unsigned
#define SPEC_SIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_signed
#define SPEC_SCLS(x) validateLink(x, "SPEC_SCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.sclass
#define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isenum
#define SPEC_OCLS(x) validateLink(x, "SPEC_OCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.oclass
#define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_static
#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_extern
#define SPEC_CODE(x) validateLink(x, "SPEC_CODE", #x, SPECIFIER, __FILE__, __LINE__)->select.s._codesg
#define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_absadr
#define SPEC_BANK(x) validateLink(x, "SPEC_BANK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._regbank
#define SPEC_ADDR(x) validateLink(x, "SPEC_ADDR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._addr
#define SPEC_STAK(x) validateLink(x, "SPEC_STAK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._stack
#define SPEC_CVAL(x) validateLink(x, "SPEC_CVAL", #x, SPECIFIER, __FILE__, __LINE__)->select.s.const_val
#define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart
#define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength
#define SPEC_BUNNAMED(x) validateLink(x, "SPEC_BUNNAMED", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_bitUnnamed
#define SPEC_NEEDSPAR(x) validateLink(x, "SPEC_NEEDSPAR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_needspar
/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on
* function type symbols, which obviously cannot
* be of BIT type. Therefore, we recycle the
* _bitStart field instead of defining a new field.
*/
#define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart
#define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_volatile
#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_const
#define SPEC_RESTRICT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_restrict
#define SPEC_ADDRSPACE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.addrspace
#define SPEC_STRUCT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.v_struct
#define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_typedef
#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isregparm
#define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg
#define SPEC_INLINE(x) validateLink(x, "SPEC_INLINE", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_inline
#define SPEC_NORETURN(x) validateLink(x, "SPEC_NORETURN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_noreturn
#define SPEC_ALIGNAS(x) validateLink(x, "SPEC_ALIGNAS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_alignas
/* type check macros */
#define IS_DECL(x) ( x && x->xclass == DECLARATOR )
#define IS_SPEC(x) ( x && x->xclass == SPECIFIER )
#define IS_ARRAY(x) (IS_DECL(x) && DCL_TYPE(x) == ARRAY)
#define IS_DATA_PTR(x) (IS_DECL(x) && DCL_TYPE(x) == POINTER)
#define IS_SMALL_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \
DCL_TYPE(x) == IPOINTER || \
DCL_TYPE(x) == PPOINTER ))
#define IS_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \
DCL_TYPE(x) == FPOINTER || \
DCL_TYPE(x) == GPOINTER || \
DCL_TYPE(x) == IPOINTER || \
DCL_TYPE(x) == PPOINTER || \
DCL_TYPE(x) == EEPPOINTER || \
DCL_TYPE(x) == CPOINTER || \
DCL_TYPE(x) == UPOINTER ))
#define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x))
#define IS_PTR_RESTRICT(x) (IS_PTR(x) && DCL_PTR_RESTRICT(x))
#define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER)
#define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER)
#define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER)
#define IS_FUNCPTR(x) (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next))
#define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION)
#define IS_LONG(x) (IS_SPEC(x) && x->select.s.b_long)
#define IS_LONGLONG(x) (IS_SPEC(x) && x->select.s.b_longlong)
#define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s.b_unsigned)
#define IS_TYPEDEF(x) (IS_SPEC(x) && x->select.s.b_typedef)
#define IS_CONSTANT(x) (isConstant (x))
#define IS_RESTRICT(x) (isRestrict (x))
#define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT)
#define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s.b_absadr )
#define IS_REGISTER(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER)
#define IS_RENT(x) (IS_SPEC(x) && x->select.s._reent )
#define IS_STATIC(x) (IS_SPEC(x) && SPEC_STAT(x))
#define IS_INLINE(x) (IS_SPEC(x) && SPEC_INLINE(x))
#define IS_NORETURN(x) (IS_SPEC(x) && SPEC_NORETURN(x))
#define IS_INT(x) (IS_SPEC(x) && x->select.s.noun == V_INT)
#define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID)
#define IS_BOOL(x) (IS_SPEC(x) && x->select.s.noun == V_BOOL)
#define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR)
#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s.b_extern)
#define IS_VOLATILE(x) (isVolatile (x))
#define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \
x->select.s.noun == V_BOOL || \
x->select.s.noun == V_CHAR || \
x->select.s.noun == V_BITFIELD || \
x->select.s.noun == V_BBITFIELD || \
x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT ))
#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \
x->select.s.noun == V_BBITFIELD ))
#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \
x->select.s.noun == V_BBITFIELD || \
x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT ))
#define IS_BIT(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT ))
#define IS_BOOLEAN(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \
x->select.s.noun == V_SBIT || \
x->select.s.noun == V_BBITFIELD || \
x->select.s.noun == V_BOOL ))
#define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
#define IS_FIXED16X16(x) (IS_SPEC(x) && x->select.s.noun == V_FIXED16X16)
#define IS_FIXED(x) (IS_FIXED16X16(x))
#define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x) || IS_FIXED(x))
#define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x))
#define IS_LITERAL(x) (IS_SPEC(x) && x->select.s.sclass == S_LITERAL)
#define IS_CODE(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_CODE)
#define IS_REGPARM(x) (IS_SPEC(x) && SPEC_REGPARM(x))
#define IS_VALID_PARAMETER_STORAGE_CLASS_SPEC(x) (!SPEC_TYPEDEF(x) && !SPEC_EXTR(x) && !SPEC_STAT(x) && SPEC_SCLS(x) != S_AUTO)
/* symbol check macros */
#define IS_AUTO(x) (x->level && !IS_STATIC(x->etype) && !IS_EXTERN(x->etype))
/* forward declaration for the global vars */
extern bucket *SymbolTab[];
extern bucket *StructTab[];
extern bucket *TypedefTab[];
extern bucket *LabelTab[];
extern bucket *enumTab[];
extern bucket *AddrspaceTab[];
extern symbol *fsadd;
extern symbol *fssub;
extern symbol *fsmul;
extern symbol *fsdiv;
extern symbol *fseq;
extern symbol *fsneq;
extern symbol *fslt;
extern symbol *fps16x16_add;
extern symbol *fps16x16_sub;
extern symbol *fps16x16_mul;
extern symbol *fps16x16_div;
extern symbol *fps16x16_eq;
extern symbol *fps16x16_neq;
extern symbol *fps16x16_lt;
extern symbol *fps16x16_lteq;
extern symbol *fps16x16_gt;
extern symbol *fps16x16_gteq;
/* Dims: mul/div/mod, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED/BOTH */
extern symbol *muldiv[3][4][4];
/* 16 x 16 -> 32 multiplication SIGNED/UNSIGNED */
extern symbol *muls16tos32[2];
/* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */
extern sym_link *multypes[4][2];
/* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/USIGNED */
extern symbol *conv[2][4][2];
/* Dims: to/from fixed16x16, BYTE/WORD/DWORD/QWORD/FLOAT, SIGNED/USIGNED */
extern symbol *fp16x16conv[2][5][2];
/* Dims: shift left/shift right, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */
extern symbol *rlrr[2][4][2];
extern symbol *memcpy_builtin;
#define SCHARTYPE multypes[0][0]
#define UCHARTYPE multypes[0][1]
#define INTTYPE multypes[1][0]
#define UINTTYPE multypes[1][1]
#define LONGTYPE multypes[2][0]
#define ULONGTYPE multypes[2][1]
#define LONGLONGTYPE multypes[3][0]
#define ULONGLONGTYPE multypes[3][1]
extern sym_link *floatType;
extern sym_link *fixed16x16Type;
#include "SDCCval.h"
typedef enum
{
RESULT_TYPE_NONE = 0, /* operands will be promoted to int */
RESULT_TYPE_BOOL,
RESULT_TYPE_CHAR,
RESULT_TYPE_INT,
RESULT_TYPE_OTHER, /* operands will be promoted to int */
RESULT_TYPE_IFX,
RESULT_TYPE_GPTR /* operands will be promoted to generic ptr */
} RESULT_TYPE;
/* forward definitions for the symbol table related functions */
void initSymt ();
symbol *newSymbol (const char *, long);
sym_link *newLink (SYM_LINK_CLASS);
sym_link *newFloatLink ();
structdef *newStruct (const char *);
void addDecl (symbol *, int, sym_link *);
sym_link *finalizeSpec (sym_link *);
sym_link *mergeSpec (sym_link *, sym_link *, const char *name);
sym_link *mergeDeclSpec (sym_link *, sym_link *, const char *name);
symbol *reverseSyms (symbol *);
sym_link *reverseLink (sym_link *);
symbol *copySymbol (const symbol *);
symbol *copySymbolChain (const symbol *);
void printSymChain (symbol *, int);
void printStruct (structdef *, int);
char *genSymName (long);
sym_link *getSpec (sym_link *);
int compStructSize (int, structdef *);
sym_link *copyLinkChain (const sym_link *);
int checkDecl (symbol *, int);
void checkBasic (sym_link *, sym_link *);
value *checkPointerIval (sym_link *, value *);
value *checkStructIval (symbol *, value *);
value *checkArrayIval (sym_link *, value *);
value *checkIval (sym_link *, value *);
unsigned int getSize (sym_link *);
unsigned int bitsForType (sym_link *);
sym_link *newIntLink ();
sym_link *newCharLink ();
sym_link *newLongLink ();
sym_link *newBoolLink ();
sym_link *newVoidLink ();
int compareType (sym_link *, sym_link *);
int compareTypeExact (sym_link *, sym_link *, long);
int compareTypeInexact (sym_link *, sym_link *);
int checkFunction (symbol *, symbol *);
void cleanUpLevel (bucket **, long);
void cleanUpBlock (bucket **, int);
symbol *getAddrspace (sym_link *type);
int funcInChain (sym_link *);
void addSymChain (symbol **);
sym_link *structElemType (sym_link *, value *);
symbol *getStructElement (structdef *, symbol *);
sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int);
void processFuncPtrArgs (sym_link *);
void processFuncArgs (symbol *);
int isSymbolEqual (const symbol *, const symbol *);
int powof2 (TYPE_TARGET_ULONG);
void dbuf_printTypeChain (sym_link *, struct dbuf_s *);
void printTypeChain (sym_link *, FILE *);
void printTypeChainRaw (sym_link *, FILE *);
void initCSupport ();
void initBuiltIns ();
void pointerTypes (sym_link *, sym_link *);
void cdbStructBlock (int);
void initHashT ();
bucket *newBucket ();
void addSym (bucket **, void *, char *, long, int, int checkType);
void deleteSym (bucket **, void *, const char *);
void *findSym (bucket **, void *, const char *);
void *findSymWithLevel (bucket **, struct symbol *);
void *findSymWithBlock (bucket **, struct symbol *, int, long);
void changePointer (sym_link * p);
void checkTypeSanity (sym_link * etype, const char *name);
sym_link *typeFromStr (const char *);
STORAGE_CLASS sclsFromPtr (sym_link * ptr);
sym_link *newEnumType (symbol *);
void promoteAnonStructs (int, structdef *);
int isConstant (sym_link * type);
int isVolatile (sym_link * type);
int isRestrict (sym_link * type);
value *aggregateToPointer (value *);
extern char *nounName (sym_link *); /* noun strings */
extern void printFromToType (sym_link *, sym_link *);
#endif
|