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 */
60struct 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 */
82typedef struct SymEntry SymEntry;
83struct 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 */
115extern SymEntry* SymList;
116
117/* Pointer to last defined symbol */
118extern SymEntry* SymLast;
119
120
121
122/*****************************************************************************/
123/* Code */
124/*****************************************************************************/
125
126
127
128SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags);
129/* Allocate a symbol table entry, initialize and return it */
130
131int 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)
141INLINE 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)
151INLINE 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
160void SymTransferExprRefs (SymEntry* From, SymEntry* To);
161/* Transfer all expression references from one symbol to another. */
162
163void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned char AddrSize, unsigned Flags);
164/* Mark a symbol as defined */
165
166void SymRef (SymEntry* Sym);
167/* Mark the given symbol as referenced */
168
169void SymImport (SymEntry* Sym, unsigned char AddrSize, unsigned Flags);
170/* Mark the given symbol as an imported symbol */
171
172void SymExport (SymEntry* Sym, unsigned char AddrSize, unsigned Flags);
173/* Mark the given symbol as an exported symbol */
174
175void 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
180void 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
185void 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
192void SymExportFromGlobal (SymEntry* S);
193/* Called at the end of assembly. Converts a global symbol that is defined
194** into an export.
195*/
196
197void 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)
203INLINE 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)
213INLINE 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)
223INLINE 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)
234INLINE 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)
245INLINE 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
255int 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)
261INLINE 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)
272INLINE 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)
283INLINE 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)
294INLINE 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
304struct 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
309struct ExprNode* GetSymExpr (SymEntry* Sym);
310/* Get the expression for a non-const symbol */
311
312const 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)
318INLINE 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)
328INLINE 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
339long 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
344unsigned GetSymImportId (const SymEntry* Sym);
345/* Return the import id for the given symbol */
346
347unsigned GetSymExportId (const SymEntry* Sym);
348/* Return the export id for the given symbol */
349
350unsigned 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