1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* symentry.h */ |
4 | /* */ |
5 | /* Symbol table entries for the cc65 C compiler */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 2000-2013, Ullrich von Bassewitz */ |
10 | /* Roemerstrasse 52 */ |
11 | /* D-70794 Filderstadt */ |
12 | /* EMail: uz@cc65.org */ |
13 | /* */ |
14 | /* */ |
15 | /* This software is provided 'as-is', without any expressed or implied */ |
16 | /* warranty. In no event will the authors be held liable for any damages */ |
17 | /* arising from the use of this software. */ |
18 | /* */ |
19 | /* Permission is granted to anyone to use this software for any purpose, */ |
20 | /* including commercial applications, and to alter it and redistribute it */ |
21 | /* freely, subject to the following restrictions: */ |
22 | /* */ |
23 | /* 1. The origin of this software must not be misrepresented; you must not */ |
24 | /* claim that you wrote the original software. If you use this software */ |
25 | /* in a product, an acknowledgment in the product documentation would be */ |
26 | /* appreciated but is not required. */ |
27 | /* 2. Altered source versions must be plainly marked as such, and must not */ |
28 | /* be misrepresented as being the original software. */ |
29 | /* 3. This notice may not be removed or altered from any source */ |
30 | /* distribution. */ |
31 | /* */ |
32 | /*****************************************************************************/ |
33 | |
34 | |
35 | |
36 | #ifndef SYMENTRY_H |
37 | #define SYMENTRY_H |
38 | |
39 | |
40 | |
41 | #include <stdio.h> |
42 | |
43 | /* common */ |
44 | #include "coll.h" |
45 | #include "inline.h" |
46 | |
47 | /* cc65 */ |
48 | #include "datatype.h" |
49 | #include "declattr.h" |
50 | |
51 | |
52 | |
53 | /*****************************************************************************/ |
54 | /* Forwards */ |
55 | /*****************************************************************************/ |
56 | |
57 | |
58 | |
59 | struct Segments; |
60 | struct LiteralPool; |
61 | struct CodeEntry; |
62 | |
63 | |
64 | |
65 | /*****************************************************************************/ |
66 | /* struct SymEntry */ |
67 | /*****************************************************************************/ |
68 | |
69 | |
70 | |
71 | /* Storage classes and flags */ |
72 | #define SC_AUTO 0x0001U /* Auto variable */ |
73 | #define SC_REGISTER 0x0002U /* Register variable */ |
74 | #define SC_STATIC 0x0004U /* Static */ |
75 | #define SC_EXTERN 0x0008U /* Extern linkage */ |
76 | |
77 | #define SC_ENUM 0x0030U /* An enum */ |
78 | #define SC_CONST 0x0020U /* A numeric constant with a type */ |
79 | #define SC_LABEL 0x0040U /* A goto label */ |
80 | #define SC_PARAM 0x0080U /* A function parameter */ |
81 | #define SC_FUNC 0x0100U /* A function */ |
82 | |
83 | #define SC_DEFTYPE 0x0200U /* Parameter has default type (=int, old style) */ |
84 | #define SC_STORAGE 0x0400U /* Symbol with associated storage */ |
85 | #define SC_DEFAULT 0x0800U /* Flag: default storage class was used */ |
86 | |
87 | #define SC_DEF 0x1000U /* Symbol is defined */ |
88 | #define SC_REF 0x2000U /* Symbol is referenced */ |
89 | |
90 | #define SC_TYPE 0x4000U /* This is a type, struct, typedef, etc. */ |
91 | #define SC_STRUCT 0x4001U /* Struct */ |
92 | #define SC_UNION 0x4002U /* Union */ |
93 | #define SC_STRUCTFIELD 0x4003U /* Struct or union field */ |
94 | #define SC_BITFIELD 0x4004U /* A bit-field inside a struct or union */ |
95 | #define SC_TYPEDEF 0x4005U /* A typedef */ |
96 | #define SC_TYPEMASK 0x400FU /* Mask for above types */ |
97 | |
98 | #define SC_ZEROPAGE 0x8000U /* Symbol marked as zeropage */ |
99 | |
100 | #define SC_HAVEATTR 0x10000U /* Symbol has attributes */ |
101 | |
102 | #define SC_GOTO 0x20000U |
103 | #define SC_SPADJUSTMENT 0x40000U |
104 | #define SC_GOTO_IND 0x80000U /* Indirect goto */ |
105 | |
106 | |
107 | |
108 | |
109 | /* Label definition or reference */ |
110 | typedef struct DefOrRef DefOrRef; |
111 | struct DefOrRef { |
112 | unsigned Line; |
113 | long LocalsBlockId; |
114 | unsigned Flags; |
115 | int StackPtr; |
116 | unsigned Depth; |
117 | unsigned LateSP_Label; |
118 | }; |
119 | |
120 | /* Symbol table entry */ |
121 | typedef struct SymEntry SymEntry; |
122 | struct SymEntry { |
123 | SymEntry* NextHash; /* Next entry in hash list */ |
124 | SymEntry* PrevSym; /* Previous symbol in dl list */ |
125 | SymEntry* NextSym; /* Next symbol double linked list */ |
126 | SymEntry* Link; /* General purpose single linked list */ |
127 | struct SymTable* Owner; /* Symbol table the symbol is in */ |
128 | unsigned Flags; /* Symbol flags */ |
129 | Type* Type; /* Symbol type */ |
130 | Collection* Attr; /* Attribute list if any */ |
131 | char* AsmName; /* Assembler name if any */ |
132 | |
133 | /* Data that differs for the different symbol types */ |
134 | union { |
135 | |
136 | /* Offset for locals or struct members */ |
137 | int Offs; |
138 | |
139 | /* Label name for static symbols */ |
140 | struct { |
141 | unsigned Label; |
142 | Collection *DefsOrRefs; |
143 | struct CodeEntry *IndJumpFrom; |
144 | } L; |
145 | |
146 | /* Value of SP adjustment needed after forward 'goto' */ |
147 | unsigned short SPAdjustment; |
148 | |
149 | /* Register bank offset and offset of the saved copy on stack for |
150 | ** register variables. |
151 | */ |
152 | struct { |
153 | int RegOffs; |
154 | int SaveOffs; |
155 | } R; |
156 | |
157 | /* Value for constants (including enums) */ |
158 | long ConstVal; |
159 | |
160 | /* Data for structs/unions */ |
161 | struct { |
162 | struct SymTable* SymTab; /* Member symbol table */ |
163 | unsigned Size; /* Size of the union/struct */ |
164 | } S; |
165 | |
166 | /* Data for bit fields */ |
167 | struct { |
168 | unsigned Offs; /* Byte offset into struct */ |
169 | unsigned BitOffs; /* Bit offset into storage unit */ |
170 | unsigned BitWidth; /* Width in bits */ |
171 | } B; |
172 | |
173 | /* Data for functions */ |
174 | struct { |
175 | struct FuncDesc* Func; /* Function descriptor */ |
176 | struct Segments* Seg; /* Segments for this function */ |
177 | struct LiteralPool* LitPool; /* Literal pool for this function */ |
178 | } F; |
179 | |
180 | /* Segment name for tentantive global definitions */ |
181 | const char* BssName; |
182 | } V; |
183 | char Name[1]; /* Name, dynamically allocated */ |
184 | }; |
185 | |
186 | |
187 | |
188 | /*****************************************************************************/ |
189 | /* Code */ |
190 | /*****************************************************************************/ |
191 | |
192 | |
193 | |
194 | SymEntry* NewSymEntry (const char* Name, unsigned Flags); |
195 | /* Create a new symbol table with the given name */ |
196 | |
197 | void FreeSymEntry (SymEntry* E); |
198 | /* Free a symbol entry */ |
199 | |
200 | void DumpSymEntry (FILE* F, const SymEntry* E); |
201 | /* Dump the given symbol table entry to the file in readable form */ |
202 | |
203 | #if defined(HAVE_INLINE) |
204 | INLINE int SymIsBitField (const SymEntry* Sym) |
205 | /* Return true if the given entry is a bit-field entry */ |
206 | { |
207 | return ((Sym->Flags & SC_BITFIELD) == SC_BITFIELD); |
208 | } |
209 | #else |
210 | # define SymIsBitField(Sym) (((Sym)->Flags & SC_BITFIELD) == SC_BITFIELD) |
211 | #endif |
212 | |
213 | #if defined(HAVE_INLINE) |
214 | INLINE int SymIsTypeDef (const SymEntry* Sym) |
215 | /* Return true if the given entry is a typedef entry */ |
216 | { |
217 | return ((Sym->Flags & SC_TYPEDEF) == SC_TYPEDEF); |
218 | } |
219 | #else |
220 | # define SymIsTypeDef(Sym) (((Sym)->Flags & SC_TYPEDEF) == SC_TYPEDEF) |
221 | #endif |
222 | |
223 | #if defined(HAVE_INLINE) |
224 | INLINE int SymIsDef (const SymEntry* Sym) |
225 | /* Return true if the given entry is defined */ |
226 | { |
227 | return ((Sym->Flags & SC_DEF) == SC_DEF); |
228 | } |
229 | #else |
230 | # define SymIsDef(Sym) (((Sym)->Flags & SC_DEF) == SC_DEF) |
231 | #endif |
232 | |
233 | #if defined(HAVE_INLINE) |
234 | INLINE int SymIsRef (const SymEntry* Sym) |
235 | /* Return true if the given entry is referenced */ |
236 | { |
237 | return ((Sym->Flags & SC_REF) == SC_REF); |
238 | } |
239 | #else |
240 | # define SymIsRef(Sym) (((Sym)->Flags & SC_REF) == SC_REF) |
241 | #endif |
242 | |
243 | #if defined(HAVE_INLINE) |
244 | INLINE int SymIsRegVar (const SymEntry* Sym) |
245 | /* Return true if the given entry is a register variable */ |
246 | /* ### HACK! Fix the ugly type flags! */ |
247 | { |
248 | return ((Sym->Flags & (SC_REGISTER|SC_TYPE)) == SC_REGISTER); |
249 | } |
250 | #else |
251 | # define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_TYPE)) == SC_REGISTER) |
252 | #endif |
253 | |
254 | int SymIsOutputFunc (const SymEntry* Sym); |
255 | /* Return true if this is a function that must be output */ |
256 | |
257 | #if defined(HAVE_INLINE) |
258 | INLINE const char* SymGetAsmName (const SymEntry* Sym) |
259 | /* Return the assembler label name for the symbol (beware: may be NULL!) */ |
260 | { |
261 | return Sym->AsmName; |
262 | } |
263 | #else |
264 | # define SymGetAsmName(Sym) ((Sym)->AsmName) |
265 | #endif |
266 | |
267 | const DeclAttr* SymGetAttr (const SymEntry* Sym, DeclAttrType AttrType); |
268 | /* Return an attribute for this symbol or NULL if the attribute does not exist */ |
269 | |
270 | #if defined(HAVE_INLINE) |
271 | INLINE int SymHasAttr (const SymEntry* Sym, DeclAttrType A) |
272 | /* Return true if the symbol has the given attribute */ |
273 | { |
274 | return (SymGetAttr (Sym, A) != 0); |
275 | } |
276 | #else |
277 | # define SymHasAttr(Sym, A) (SymGetAttr (Sym, A) != 0) |
278 | #endif |
279 | |
280 | void SymUseAttr (SymEntry* Sym, struct Declaration* D); |
281 | /* Use the attributes from the declaration for this symbol */ |
282 | |
283 | void SymSetAsmName (SymEntry* Sym); |
284 | /* Set the assembler name for an external symbol from the name of the symbol */ |
285 | |
286 | void CvtRegVarToAuto (SymEntry* Sym); |
287 | /* Convert a register variable to an auto variable */ |
288 | |
289 | void ChangeSymType (SymEntry* Entry, Type* T); |
290 | /* Change the type of the given symbol */ |
291 | |
292 | void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); |
293 | /* Change the assembler name of the symbol */ |
294 | |
295 | int HasAnonName (const SymEntry* Entry); |
296 | /* Return true if the symbol entry has an anonymous name */ |
297 | |
298 | |
299 | |
300 | /* End of symentry.h */ |
301 | |
302 | #endif |
303 | |