1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* symentry.h */ |
4 | /* */ |
5 | /* Symbol table entry forward for the ca65 macroassembler */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 1998-2012, 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 | /* common */ |
42 | #include "cddefs.h" |
43 | #include "coll.h" |
44 | #include "filepos.h" |
45 | #include "inline.h" |
46 | #include "strbuf.h" |
47 | |
48 | /* ca65 */ |
49 | #include "spool.h" |
50 | |
51 | |
52 | |
53 | /*****************************************************************************/ |
54 | /* Data */ |
55 | /*****************************************************************************/ |
56 | |
57 | |
58 | |
59 | /* Forwards */ |
60 | struct HLLDbgSym; |
61 | |
62 | /* Bits for the Flags value in SymEntry */ |
63 | #define SF_NONE 0x0000 /* Empty flag set */ |
64 | #define SF_USER 0x0001 /* User bit */ |
65 | #define SF_UNUSED 0x0002 /* Unused entry */ |
66 | #define SF_EXPORT 0x0004 /* Export this symbol */ |
67 | #define SF_IMPORT 0x0008 /* Import this symbol */ |
68 | #define SF_GLOBAL 0x0010 /* Global symbol */ |
69 | #define SF_LOCAL 0x0020 /* Cheap local symbol */ |
70 | #define SF_LABEL 0x0040 /* Used as a label */ |
71 | #define SF_VAR 0x0080 /* Variable symbol */ |
72 | #define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */ |
73 | #define SF_FIXED 0x0200 /* May not be trampoline */ |
74 | #define SF_MULTDEF 0x1000 /* Multiply defined symbol */ |
75 | #define SF_DEFINED 0x2000 /* Defined */ |
76 | #define SF_REFERENCED 0x4000 /* Referenced */ |
77 | |
78 | /* Combined values */ |
79 | #define SF_REFIMP (SF_REFERENCED|SF_IMPORT) /* A ref'd import */ |
80 | |
81 | /* Structure of a symbol table entry */ |
82 | typedef struct SymEntry SymEntry; |
83 | struct SymEntry { |
84 | SymEntry* Left; /* Lexically smaller entry */ |
85 | SymEntry* Right; /* Lexically larger entry */ |
86 | SymEntry* List; /* List of all entries */ |
87 | SymEntry* Locals; /* Root of subtree for local symbols */ |
88 | union { |
89 | struct SymTable* Tab; /* Table this symbol is in */ |
90 | struct SymEntry* Entry; /* Parent for cheap locals */ |
91 | } Sym; |
92 | Collection DefLines; /* Line infos for definition */ |
93 | Collection RefLines; /* Line infos for references */ |
94 | FilePos* GuessedUse[1]; /* File position where symbol |
95 | ** address size was guessed, and the |
96 | ** smallest possible addressing was NOT |
97 | ** used. Currently only for zero page |
98 | ** addressing |
99 | */ |
100 | struct HLLDbgSym* HLLSym; /* Symbol from high level language */ |
101 | unsigned Flags; /* Symbol flags */ |
102 | unsigned DebugSymId; /* Debug symbol id */ |
103 | unsigned ImportId; /* Id of import if this is one */ |
104 | unsigned ExportId; /* Id of export if this is one */ |
105 | struct ExprNode* Expr; /* Symbol expression */ |
106 | Collection ExprRefs; /* Expressions using this symbol */ |
107 | unsigned char ExportSize; /* Export address size */ |
108 | unsigned char AddrSize; /* Address size of label */ |
109 | unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ |
110 | /* ...actually value+1 (used as flag) */ |
111 | unsigned Name; /* Name index in global string pool */ |
112 | }; |
113 | |
114 | /* List of all symbol table entries */ |
115 | extern SymEntry* SymList; |
116 | |
117 | /* Pointer to last defined symbol */ |
118 | extern SymEntry* SymLast; |
119 | |
120 | |
121 | |
122 | /*****************************************************************************/ |
123 | /* Code */ |
124 | /*****************************************************************************/ |
125 | |
126 | |
127 | |
128 | SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags); |
129 | /* Allocate a symbol table entry, initialize and return it */ |
130 | |
131 | int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E); |
132 | /* Search in the given tree for a name. If we find the symbol, the function |
133 | ** will return 0 and put the entry pointer into E. If we did not find the |
134 | ** symbol, and the tree is empty, E is set to NULL. If the tree is not empty, |
135 | ** E will be set to the last entry, and the result of the function is <0 if |
136 | ** the entry should be inserted on the left side, and >0 if it should get |
137 | ** inserted on the right side. |
138 | */ |
139 | |
140 | #if defined(HAVE_INLINE) |
141 | INLINE void SymAddExprRef (SymEntry* Sym, struct ExprNode* Expr) |
142 | /* Add an expression reference to this symbol */ |
143 | { |
144 | CollAppend (&Sym->ExprRefs, Expr); |
145 | } |
146 | #else |
147 | #define SymAddExprRef(Sym,Expr) CollAppend (&(Sym)->ExprRefs, Expr) |
148 | #endif |
149 | |
150 | #if defined(HAVE_INLINE) |
151 | INLINE void SymDelExprRef (SymEntry* Sym, struct ExprNode* Expr) |
152 | /* Delete an expression reference to this symbol */ |
153 | { |
154 | CollDeleteItem (&Sym->ExprRefs, Expr); |
155 | } |
156 | #else |
157 | #define SymDelExprRef(Sym,Expr) CollDeleteItem (&(Sym)->ExprRefs, Expr) |
158 | #endif |
159 | |
160 | void SymTransferExprRefs (SymEntry* From, SymEntry* To); |
161 | /* Transfer all expression references from one symbol to another. */ |
162 | |
163 | void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned char AddrSize, unsigned Flags); |
164 | /* Mark a symbol as defined */ |
165 | |
166 | void SymRef (SymEntry* Sym); |
167 | /* Mark the given symbol as referenced */ |
168 | |
169 | void SymImport (SymEntry* Sym, unsigned char AddrSize, unsigned Flags); |
170 | /* Mark the given symbol as an imported symbol */ |
171 | |
172 | void SymExport (SymEntry* Sym, unsigned char AddrSize, unsigned Flags); |
173 | /* Mark the given symbol as an exported symbol */ |
174 | |
175 | void SymGlobal (SymEntry* Sym, unsigned char AddrSize, unsigned Flags); |
176 | /* Mark the given symbol as a global symbol, that is, as a symbol that is |
177 | ** either imported or exported. |
178 | */ |
179 | |
180 | void SymConDes (SymEntry* Sym, unsigned char AddrSize, unsigned Type, unsigned Prio); |
181 | /* Mark the given symbol as a module constructor/destructor. This will also |
182 | ** mark the symbol as an export. Initializers may never be zero page symbols. |
183 | */ |
184 | |
185 | void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize); |
186 | /* Mark the address size of the given symbol as guessed. The address size |
187 | ** passed as argument is the one NOT used, because the actual address size |
188 | ** wasn't known. Example: Zero page addressing was not used because symbol |
189 | ** is undefined, and absolute addressing was available. |
190 | */ |
191 | |
192 | void SymExportFromGlobal (SymEntry* S); |
193 | /* Called at the end of assembly. Converts a global symbol that is defined |
194 | ** into an export. |
195 | */ |
196 | |
197 | void SymImportFromGlobal (SymEntry* S); |
198 | /* Called at the end of assembly. Converts a global symbol that is undefined |
199 | ** into an import. |
200 | */ |
201 | |
202 | #if defined(HAVE_INLINE) |
203 | INLINE int SymIsDef (const SymEntry* S) |
204 | /* Return true if the given symbol is already defined */ |
205 | { |
206 | return (S->Flags & SF_DEFINED) != 0; |
207 | } |
208 | #else |
209 | # define SymIsDef(S) (((S)->Flags & SF_DEFINED) != 0) |
210 | #endif |
211 | |
212 | #if defined(HAVE_INLINE) |
213 | INLINE int SymIsRef (const SymEntry* S) |
214 | /* Return true if the given symbol has been referenced */ |
215 | { |
216 | return (S->Flags & SF_REFERENCED) != 0; |
217 | } |
218 | #else |
219 | # define SymIsRef(S) (((S)->Flags & SF_REFERENCED) != 0) |
220 | #endif |
221 | |
222 | #if defined(HAVE_INLINE) |
223 | INLINE int SymIsImport (const SymEntry* S) |
224 | /* Return true if the given symbol is marked as import */ |
225 | { |
226 | /* Check the import flag */ |
227 | return (S->Flags & SF_IMPORT) != 0; |
228 | } |
229 | #else |
230 | # define SymIsImport(S) (((S)->Flags & SF_IMPORT) != 0) |
231 | #endif |
232 | |
233 | #if defined(HAVE_INLINE) |
234 | INLINE int SymIsExport (const SymEntry* S) |
235 | /* Return true if the given symbol is marked as export */ |
236 | { |
237 | /* Check the export flag */ |
238 | return (S->Flags & SF_EXPORT) != 0; |
239 | } |
240 | #else |
241 | # define SymIsExport(S) (((S)->Flags & SF_EXPORT) != 0) |
242 | #endif |
243 | |
244 | #if defined(HAVE_INLINE) |
245 | INLINE int SymIsVar (const SymEntry* S) |
246 | /* Return true if the given symbol is marked as variable */ |
247 | { |
248 | /* Check the variable flag */ |
249 | return (S->Flags & SF_VAR) != 0; |
250 | } |
251 | #else |
252 | # define SymIsVar(S) (((S)->Flags & SF_VAR) != 0) |
253 | #endif |
254 | |
255 | int SymIsConst (const SymEntry* Sym, long* Val); |
256 | /* Return true if the given symbol has a constant value. If Val is not NULL |
257 | ** and the symbol has a constant value, store it's value there. |
258 | */ |
259 | |
260 | #if defined(HAVE_INLINE) |
261 | INLINE int SymHasExpr (const SymEntry* S) |
262 | /* Return true if the given symbol has an associated expression */ |
263 | { |
264 | /* Check the expression */ |
265 | return ((S->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED); |
266 | } |
267 | #else |
268 | # define SymHasExpr(S) (((S)->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED) |
269 | #endif |
270 | |
271 | #if defined(HAVE_INLINE) |
272 | INLINE void SymMarkUser (SymEntry* S) |
273 | /* Set a user mark on the specified symbol */ |
274 | { |
275 | /* Set the bit */ |
276 | S->Flags |= SF_USER; |
277 | } |
278 | #else |
279 | # define SymMarkUser(S) ((S)->Flags |= SF_USER) |
280 | #endif |
281 | |
282 | #if defined(HAVE_INLINE) |
283 | INLINE void SymUnmarkUser (SymEntry* S) |
284 | /* Remove a user mark from the specified symbol */ |
285 | { |
286 | /* Reset the bit */ |
287 | S->Flags &= ~SF_USER; |
288 | } |
289 | #else |
290 | # define SymUnmarkUser(S) ((S)->Flags &= ~SF_USER) |
291 | #endif |
292 | |
293 | #if defined(HAVE_INLINE) |
294 | INLINE int SymHasUserMark (SymEntry* S) |
295 | /* Return the state of the user mark for the specified symbol */ |
296 | { |
297 | /* Check the bit */ |
298 | return (S->Flags & SF_USER) != 0; |
299 | } |
300 | #else |
301 | # define SymHasUserMark(S) (((S)->Flags & SF_USER) != 0) |
302 | #endif |
303 | |
304 | struct SymTable* GetSymParentScope (SymEntry* S); |
305 | /* Get the parent scope of the symbol (not the one it is defined in). Return |
306 | ** NULL if the symbol is a cheap local, or defined on global level. |
307 | */ |
308 | |
309 | struct ExprNode* GetSymExpr (SymEntry* Sym); |
310 | /* Get the expression for a non-const symbol */ |
311 | |
312 | const struct ExprNode* SymResolve (const SymEntry* Sym); |
313 | /* Helper function for DumpExpr. Resolves a symbol into an expression or return |
314 | ** NULL. Do not call in other contexts! |
315 | */ |
316 | |
317 | #if defined(HAVE_INLINE) |
318 | INLINE const StrBuf* GetSymName (const SymEntry* S) |
319 | /* Return the name of the symbol */ |
320 | { |
321 | return GetStrBuf (S->Name); |
322 | } |
323 | #else |
324 | # define GetSymName(S) GetStrBuf ((S)->Name) |
325 | #endif |
326 | |
327 | #if defined(HAVE_INLINE) |
328 | INLINE unsigned char GetSymAddrSize (const SymEntry* S) |
329 | /* Return the address size of the symbol. Beware: This function will just |
330 | ** return the AddrSize member, it will not look at the expression! |
331 | */ |
332 | { |
333 | return S->AddrSize; |
334 | } |
335 | #else |
336 | # define GetSymAddrSize(S) ((S)->AddrSize) |
337 | #endif |
338 | |
339 | long GetSymVal (SymEntry* Sym); |
340 | /* Return the value of a symbol assuming it's constant. FAIL will be called |
341 | ** in case the symbol is undefined or not constant. |
342 | */ |
343 | |
344 | unsigned GetSymImportId (const SymEntry* Sym); |
345 | /* Return the import id for the given symbol */ |
346 | |
347 | unsigned GetSymExportId (const SymEntry* Sym); |
348 | /* Return the export id for the given symbol */ |
349 | |
350 | unsigned GetSymInfoFlags (const SymEntry* Sym, long* ConstVal); |
351 | /* Return a set of flags used when writing symbol information into a file. |
352 | ** If the SYM_CONST bit is set, ConstVal will contain the constant value |
353 | ** of the symbol. The result does not include the condes count. |
354 | ** See common/symdefs.h for more information. |
355 | */ |
356 | |
357 | |
358 | |
359 | /* End of symentry.h */ |
360 | |
361 | #endif |
362 | |