Rune - Change regsave burden for syscalls
[rune.git] / librune / decl.h
1 /*
2  * DECL.H
3  *
4  * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved.  See the  
5  *    COPYRIGHT file at the base of the distribution.
6  */
7
8 struct Exp;
9 struct SemGroup;
10 struct SGDepend;
11 struct Declaration;
12 struct RunContext;
13 struct GenContext;
14
15 typedef void (*ic_func_t)(struct Declaration *d, LValueStor *lvs);
16
17 /*
18  * Scope - scope associated with declaration
19  *
20  * WARNING: Must match classes/sys/runetime.d
21  */
22
23 typedef struct Scope {
24         int     s_Flags;                /* SCOPE_* flags */
25         int     s_AlignOverride;        /* __align(%d) override */
26 } Scope;
27
28 #define INIT_SCOPE(flags) { flags, 0 }
29
30
31 /*
32  * Declaration - a qualified declaration
33  *
34  *      This structure represents a declaration.  A declaration is anything
35  *      with an identifier and scope.
36  *
37  *      Declarations are grouped in SemGroup's.  d_Offset is typically
38  *      assigned for DOP_STORAGE declarations but it should be noted that
39  *      SemGroups related to procedures are collapsed into a single set
40  *      of offsets relative to the top-level SemGroup for the procedure,
41  *      so d_Offset in a deeper SemGroup  an exceed its sg_Bytes.
42  *
43  *      d_Bytes almost always matches the declaration's type size, but
44  *      there are certain cases where it will not.  A declaration representing
45  *      an LVALUE procedure argument, for example, has a size of a pointer
46  *      (for pass by reference) even though the underlying type may be
47  *      an object.
48  *
49  *      d_SRNext is based at sg_SRBase, and is resolved at resolve-time.
50  *      This is a linked list of storage declarations which represent 
51  *      reference-tracked items such as lvalues (in argument lists), and
52  *      pointers.
53  *
54  *      (note 1):  d_Level is usually d_MyGroup, except in a subclass when
55  *      we pull declarations down from the superclass, in which case it
56  *      points at the superclass (or higher superclasses) for those 
57  *      declarations.  It is used when our semgroup is being searched for
58  *      our id to locate the correct id.   d_Search is what we have to use
59  *      when we are searching this declaration's object for sub identifiers.
60  */
61 typedef RUNE_HEAD(decllist, Declaration) decllist_t;
62
63 typedef struct Declaration {
64         RUNE_ENTRY(Declaration) d_Node;
65         struct Parse    *d_Parse;
66         struct Declaration *d_HNext;    /* id hash table chain */
67         struct Declaration *d_SRNext;   /* pointer or lvalue storage chain */
68         struct Declaration *d_CNext;    /* constructor chain */ 
69         struct Declaration *d_DNext;    /* destructor chain */
70         struct Declaration *d_GNext;    /* global constructor/destructor chn */
71         struct Declaration *d_ONext;    /* operid hash table chain */
72         int             d_Op;           /* declaration opcode */
73         int8_t          d_Storage;      /* (resolver) GENSTAT_* storage mode */
74         int8_t          d_Dummy01;
75         int8_t          d_Dummy02;
76         int8_t          d_Dummy03;
77         string_t        d_Id;           /* identifier or NULL */
78         struct SemGroup *d_Level;       /* When searching for us (note 1) */
79         struct SemGroup *d_Search;      /* when searching through (note 1) */
80         Scope           d_Scope;        /* scope of declaration */
81         int             d_Flags;
82         int             d_BackendId;
83         runesize_t      d_Bytes;        /* size of declaration (see note) */
84         runesize_t      d_AlignMask;
85         runesize_t      d_Offset;       /* see note above */
86         runesize_t      d_TmpBytes;     /* tmpspace required for *_AssExp */
87         runesize_t      d_InfoIndex;    /* PointerInfo index */
88         int             d_Index;        /* index on SemGroup list */
89         int             d_DynIndex;     /* dynamic index */
90         struct SemGroup *d_MyGroup;     /* semantic grouping */
91         struct SemGroup *d_ImportSemGroup; /* upwards traversal for search */
92         struct Stmt     *d_Stmt;        /* only if declaration statement */
93         LexRef          d_LexRef;       /* for error reporting */
94         struct Declaration *d_Super;    /* decl in superclass (semantic srch) */
95         struct Declaration *d_SubBase;  /* refined decls */
96         struct Declaration *d_SubNext;  /* link for refined decls */
97         union {
98                 struct {
99                         struct SemGroup *ed_SemGroup; /* semantic grouping */
100                         Type            *ed_Super;    /* super class (type) */
101                 } ClassDecl;
102                 struct {
103                         Type            *ed_Type;     /* type */
104                         struct Exp      *ed_AssExp;   /* initialization */
105                         void            *ed_DLLAddr;  /* DLL (C lang) ifc */
106                 } StorDecl;
107                 struct {
108                         struct SemGroup *ed_SemGroup; /* semantic grouping */
109                 } ImportDecl;
110
111                 /*
112                  * Statement bodies are duplicated before being resolved
113                  * in order to be able to re-resolve them in different
114                  * contexts.
115                  */
116                 struct {
117                         Type            *ed_Type;       /* TY_PROC type */
118                         struct Stmt     *ed_ProcBody;   /* ST_Proc statement */
119                         struct Stmt     *ed_OrigBody;   /* ST_Proc statement */
120                         string_t        ed_OperId;      /* If operator */
121                         ic_func_t       ed_IFunc;       /* opt internal func */
122                         void            *ed_DLLFunc;    /* DLL (C lang) ifc */
123                 } ProcDecl;
124                 struct {
125                         void            *ed_Fill0;
126                         void            *ed_Fill1;
127                         void            *ed_Fill2;
128                         void            *ed_Fill3;
129                         void            *ed_Fill4;
130                         void            *ed_Fill5;
131                 } FILLER;
132         } u;
133 } Declaration;
134
135 /*
136  * DOP_CLASS            - represents a class definition (statement)
137  * DOP_TYPEDEF          - represents a typedef
138  * DOP_ALIAS            - represents an alias
139  * DOP_IMPORT           - represents an import (statement)
140  * DOP_PROC             - represents a procedural definition
141  * DOP_STACK_STOR       - represents non-global stack-based storage relative a 
142  *                        procedure's (single) run-time context.
143  * DOP_ARGS_STOR        - represents non-global storage for arguments to
144  *                        a procedure.
145  * DOP_GLOB_STOR        - represents global storage
146  * DOP_GROUP_STOR       - represents general storage declarations
147  *                        within class definitions, top-level declarations
148  *                        of an import (though these are always global so
149  *                        are usually DOP_GLOB_STOR), and compound type
150  *                        definitions... anything that would otherwise be
151  *                        a DOP_STACK_STOR is a DOP_GROUP_STOR in these
152  *                        contexts.
153  */
154 #define DOP_CLASS               1
155 #define DOP_TYPEDEF             2
156 #define DOP_ALIAS               3
157 #define DOP_IMPORT              4
158 #define DOP_PROC                5
159 #define DOP_ARGS_STORAGE        (6 | DOPF_STORAGE)
160 #define DOP_STACK_STORAGE       (7 | DOPF_STORAGE)
161 #define DOP_GLOBAL_STORAGE      (8 | DOPF_STORAGE)
162 #define DOP_GROUP_STORAGE       (9 | DOPF_STORAGE)
163
164 #define DOPF_STORAGE            0x0100
165
166 #define DF_RESOLVING    0x00000001
167 #define DF_RESOLVED     0x00000002
168 #define DF_SUPERCOPY    0x00000004      /* temporary flag during resolve */
169 #define DF_SUPER        0x00000008      /* special case to access super proc */
170 #define DF_GENERATING   0x00000010      /* deferred generation of global def */
171 #define DF_ADDRUSED     0x00000020      /* addr taken or used temporarily */
172 #define DF_COLLAPSING   0x00000040      /* collapse pass */
173 #define DF_COLLAPSED    0x00000080      /* collapse pass */
174 #define DF_LAYOUT       0x00000100      /* available for global data layout */
175 #define DF_ONGLIST      0x00000200      /* decl on sg->sg_GList */
176 #define DF_ONDLIST      0x00000400      /* decl on sg->sg_DList */
177 #define DF_ONCLIST      0x00000800      /* decl on sg->sg_CList */
178 #define DF_TMPRESOLVED  0x00001000      /* temporary flag to avoid loops */
179 #define DF_INLINING     0x00002000      /* inlining in progress */
180 #define DF_DYNAMICREF   0x00004000      /* dynamic method may reference */
181 #define DF_DIDEXPDUP    0x00008000      /* dup'd assexp */
182 #define DF_ONSRLIST     0x00010000
183 #define DF_DIDPULLDOWN  0x00020000      /* did procedure pull-down */
184 #define DF_ALIGNRESOLVE 0x00040000
185 #define DF_ADDROF       0x00080000      /* &field taken explicitly */
186
187 #define d_ScopeFlags    d_Scope.s_Flags
188
189 #define d_ClassDecl     u.ClassDecl
190 #define d_StorDecl      u.StorDecl
191 #define d_GlobalDecl    u.StorDecl
192 #define d_AliasDecl     u.StorDecl
193 #define d_TypedefDecl   u.StorDecl
194 #define d_ImportDecl    u.ImportDecl
195 #define d_ProcDecl      u.ProcDecl
196
197 /*
198  * SemGroup types
199  */
200 typedef enum {
201         SG_UNKNOWN = 0,
202         SG_MODULE,              /* module */
203         SG_CLASS,               /* class */
204         SG_COMPOUND,            /* compound object (other than proc-args) */
205         SG_PROCTOP,             /* procedure-top */
206         SG_PROCARGS,            /* procedure-args */
207         SG_EXEC                 /* execution (other than PROCARGS) */
208 } sg_type_t;
209
210 /*
211  * SemGroup -   Block of declarations
212  *
213  * This is used to manage blocks of declarations.  It is primarily
214  * used to generate a semantic tree for our semantic searches.
215  *
216  * Note that the SemGroup representing an IMPORT block sets SCOPE_GLOBAL
217  * on all of its declarations.
218  *
219  * WARNING!  This structure is written out as global data by the code
220  *           generator.  Do not rearrange, add, or remove fields without
221  *           also adjusting classes/sys/runtime.d
222  */
223 typedef RUNE_HEAD(sglist, SemGroup) sglist_t;
224
225 typedef struct SemGroup {
226         RUNE_ENTRY(SemGroup) sg_Node;
227         sg_type_t       sg_Type;
228         int             sg_Complexity;  /* aggregate complexity (stmt sg) */
229         struct Parse    *sg_Parse;
230         struct SemGroup *sg_Parent;     /* parent semantic group */
231         struct SemGroup *sg_AltContext; /* (resolver) alt search context */
232         struct SGDepend *sg_DepFirst;   /* dependency ordering */
233         Declaration     *sg_SRBase;     /* base of pointer/lvalue list */
234         Declaration     *sg_CBase;      /* base of constructor list */
235         Declaration     *sg_DBase;      /* base of destructor list */
236         Declaration     *sg_GBase;      /* base of global cons/dest list */
237         string_t        sg_Project;     /* shared data rendezvous (NULL ok) */
238         sglist_t        sg_SemList;     /* sub-semantic groups */
239         decllist_t      sg_DeclList;    /* list of declarations */
240         typelist_t      sg_ClassList;   /* list of [qualified] class types */
241                                         /* (also for compound types) */
242         struct Stmt     *sg_Stmt;       /* associated statement */
243         int             sg_Flags;
244         int             sg_Compat;      /* compatibility with superclass */
245         int             sg_Level;
246         int             sg_DynCount;
247         runesize_t      sg_Bytes;       /* aggregated size */
248         int             sg_NestLevel;   /* procedural nesting level */
249         int             sg_NestSize;    /* total number of nesting levels */
250         runesize_t      sg_AlignMask;
251         runesize_t      sg_BlkOffset;   /* this sg only, no children */
252         runesize_t      sg_BlkBytes;    /* this sg only, no children */
253         runesize_t      sg_GlobalBytes; /* globals are separated out */
254         runesize_t      sg_GlobalAlignMask;     /* globals are separated out */
255         runesize_t      sg_GlobalTmpBytes;      /* globals are separated out */
256         runesize_t      sg_TmpBytes;    /* temporary space required */
257         runesize_t      sg_TmpAlignMask;/* temporary space alignment reqs */
258         struct RunContext *sg_GlobalRunCtx;     /* globals are separated out */
259         void            *sg_GlobalGenCtx;       /* globals are separated out */
260         int             sg_DeclCount;   /* total number of decls */
261         int             sg_VarCount;    /* how many decls are varargs */
262         runesize_t      sg_InfoCount;   /* #of PointerInfo's needed */
263 } SemGroup;
264
265 #define SGF_RESOLVING           0x00000001      /* check for resolver loops */
266 #define SGF_RESOLVED            0x00000002      /* resolver complete */
267 #define SGF_VARARGS             0x00000004      /* (procedure only) */
268 #define SGF_ENTRY               0x00000008      /* entry module */
269 #define SGF_SEMTOP              0x00000010
270 #define SGF_NOINIT              0x00000020      /* (intrp - cache status) */
271 #define SGF_SELFCONTAINED       0x00000040      /* (import) self contained */
272 #define SGF_TMPRESOLVED         0x00000080      /* temporary space resolved */
273 #define SGF_NESTED              0x00000100      /* (proc SEMTOP), nested proc */
274 #define SGF_ISUNSIGNED          0x00000200      /* UInteger or subclass */
275 #define SGF_ISFLOATING          0x00000400      /* Float or subclass */
276 #define SGF_HASASS              0x00000800      /* contains decls w/ass */
277 #define SGF_GRESOLVING          0x00001000      /* resolve in-class globals */
278 #define SGF_GRESOLVED           0x00002000      /* resolve in-class globals */
279 #define SGF_GENERATING          0x00004000      /* avoid duplicate import gen */
280 #define SGF_ISINTEGER           0x00008000      /* UInteger or SInteger */
281 #define SGF_GHASASS             0x00010000      /* contains decls w/ass (glob)*/
282 #define SGF_ISBOOL              0x00020000      /* Bool or subclass */
283 #define SGF_COLLAPSING          0x00040000      /* collapse pass */
284 #define SGF_COLLAPSED           0x00080000      /* collapse pass */
285 #define SGF_LAYOUT              0x00100000      /* avail for global layout */
286 #define SGF_HASLVPTR            0x00200000      /* contains lvalues or ptrs */
287 #define SGF_GHASLVPTR           0x00400000      /* contains lvalues or ptrs */
288 #define SGF_DIDCTOR             0x00800000      /* ctor already generated */
289 #define SGF_ADDRUSED            0x01000000      /* rollup &obj used */
290 #define SGF_ALIGNRESOLVED       0x02000000      /* resolver */
291 #define SGF_FRESOLVING          0x04000000      /* resolver */
292 #define SGF_FRESOLVED           0x08000000      /* resolver */
293 #define SGF_DIDRESULT           0x10000000      /* resolver, thread detach */
294 #define SGF_ALTPRIORITY         0x20000000      /* alt ctx priority */
295 #define SGF_ABICALL             0x40000000      /* ABI call made (recursive)*/
296 #define SGF_GABICALL            0x80000000      /* GABI call made (recursive)*/
297
298 #define SGF_INHERIT_BASE        (SGF_VARARGS | SGF_ENTRY | SGF_SEMTOP | \
299                                  SGF_SELFCONTAINED | SGF_NESTED | \
300                                  SGF_ALTPRIORITY | SGF_ABICALL)
301
302 #define SGF_INHERIT_ALL         (SGF_INHERIT_BASE |                     \
303                                  SGF_NOINIT | SGF_ISUNSIGNED |          \
304                                  SGF_ISFLOATING | SGF_HASASS |          \
305                                  SGF_ISINTEGER | SGF_GHASASS |          \
306                                  SGF_ISBOOL | SGF_HASLVPTR |            \
307                                  SGF_GHASLVPTR)
308
309
310 /*
311  * SG dependencies (used to order global ctors)
312  */
313 typedef struct SGDepend {
314         struct SGDepend *hnext;
315         struct SGDepend *next;
316         SemGroup        *src;
317         SemGroup        *dst;
318         int             ctor_flag;
319 } SGDepend;
320
321 /*
322  * SG_COMPAT* - super class / subclass compatibility:
323  *
324  *  FULL
325  *
326  *      Requested type is a subclass of the specified superclass and both
327  *      the method calls and the storage is compatible.  Note, however,
328  *      that the subclass might extend (be larger then) the superclass.
329  *
330  *  PART
331  *
332  *      Requested type is a subclass of the specified superclass and the
333  *      method calls are compatible, but the storage is not compatible.
334  *
335  *  SUBCLASS
336  *
337  *      Requested type is a subclass of the specified superclass but the
338  *      method calls are not compatible (meaning we have to regenerate the
339  *      method call procedures for the subclass that propogate down from
340  *      the superclass).
341  *
342  *  FAIL
343  *
344  *      Requested type is not a subclass of the specified superclass.
345  */
346 #define SG_COMPAT_FULL          0
347 #define SG_COMPAT_PART          1
348 #define SG_COMPAT_SUBCLASS      2
349 #define SG_COMPAT_FAIL          3
350
351 /*
352  * FindDeclPath() flags
353  */
354
355 #define FDC_NOBACK      0x0001
356 #define FDC_NULL        0x0002
357
358 #define dassert_decl(d, cond)           if (!(cond)) DeclFatalError((d), 0)
359 #define dassert_semgrp(sg, cond)        dassert(cond)
360
361 #ifdef LIBRUNTIME
362
363 #define DeclFatalError(d, type)                         \
364         do {                                            \
365                 dpanic("Fatal Error Decl %p (%s)", d, d->d_Id); \
366         } while(0)
367
368 #else
369
370 #define DeclFatalError(d, type)                         \
371         do {                                            \
372                 DeclPrintError(d, type);                \
373                 dpanic("");                             \
374         } while(0)
375
376 #endif