Mercurial > projects > ddmd
comparison dmd/backend/Symbol.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | fd4acc376c45 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
1 module dmd.backend.Symbol; | |
2 | |
3 import dmd.backend.dt_t; | |
4 import dmd.backend.TYPE; | |
5 import dmd.backend.LIST; | |
6 import dmd.backend.block; | |
7 import dmd.backend.func_t; | |
8 import dmd.backend.enum_t; | |
9 import dmd.backend.elem; | |
10 import dmd.backend.struct_t; | |
11 import dmd.backend.template_t; | |
12 import dmd.backend.targ_types; | |
13 import dmd.backend.vec_t; | |
14 import dmd.backend.SYMIDX; | |
15 import dmd.backend.regm_t; | |
16 import dmd.backend.Util; | |
17 | |
18 struct Symbol | |
19 { | |
20 ushort id; | |
21 | |
22 Symbol* Sl; | |
23 Symbol* Sr; // left, right child | |
24 | |
25 Symbol *Snext; // next in threaded list | |
26 | |
27 dt_t* Sdt; // variables: initializer | |
28 type* Stype; // type of Symbol | |
29 | |
30 tym_t ty() | |
31 { | |
32 return Stype.Tty; | |
33 } | |
34 | |
35 union // variants for different Symbol types | |
36 { | |
37 enum_t* Senum; // SCenum | |
38 struct | |
39 { | |
40 func_t* Sfunc; // tyfunc | |
41 list_t Spath1; // SCfuncalias member functions: same as Spath | |
42 // and in same position | |
43 // SCadl: list of associated functions for ADL lookup | |
44 } | |
45 struct // SClabel | |
46 { | |
47 int Slabel; // TRUE if label was defined | |
48 block* Slabelblk; // label block | |
49 } | |
50 /// #define Senumlist Senum->SEenumlist | |
51 | |
52 struct // SClinkage | |
53 { | |
54 int Slinkage; // tym linkage bits | |
55 uint Smangle; | |
56 } | |
57 | |
58 struct | |
59 { | |
60 char Sbit; // SCfield: bit position of start of bit field | |
61 char Swidth; // SCfield: width in bits of bit field | |
62 targ_size_t Smemoff; // SCmember,SCfield: offset from start of struct | |
63 } | |
64 | |
65 elem* Svalue; /* SFLvalue: value of const | |
66 SFLdtorexp: for objects with destructor, | |
67 conditional expression to precede dtor call | |
68 */ | |
69 | |
70 struct_t* Sstruct; // SCstruct | |
71 template_t* Stemplate; // SCtemplate | |
72 Symbol* Simport; // SCextern: if dllimport Symbol, this is the | |
73 // Symbol it was imported from | |
74 | |
75 ubyte Spreg; // SCfastpar: register parameter is passed in | |
76 } | |
77 | |
78 Symbol* Sscope; // enclosing scope (could be struct tag, | |
79 // enclosing inline function for statics, | |
80 // or namespace) | |
81 ///#define isclassmember(s) ((s)->Sscope && (s)->Sscope->Sclass == SCstruct) | |
82 | |
83 const(char)* prettyIdent; // the symbol identifer as the user sees it | |
84 | |
85 enum_SC Sclass; // storage class (SCxxxx) | |
86 char Sfl; // flavor (FLxxxx) | |
87 SYMFLGS Sflags; // flag bits (SFLxxxx) | |
88 | |
89 vec_t Srange; // live range, if any | |
90 vec_t Slvreg; // when symbol is in register | |
91 targ_size_t Ssize; // tyfunc: size of function | |
92 targ_size_t Soffset; // variables: offset of Symbol in its storage class | |
93 | |
94 SYMIDX Ssymnum; // Symbol number (index into globsym.tab[]) | |
95 // SCauto,SCparameter,SCtmp,SCregpar,SCregister | |
96 | |
97 short Sseg; // segment index | |
98 | |
99 int Sweight; // usage count, the higher the number, | |
100 // the more worthwhile it is to put in | |
101 // a register | |
102 union | |
103 { | |
104 uint Sxtrnnum; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1) | |
105 uint Stypidx; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index | |
106 | |
107 struct | |
108 { | |
109 ubyte Sreglsw; | |
110 ubyte Sregmsw; | |
111 regm_t Sregm; // mask of registers | |
112 } | |
113 } | |
114 | |
115 regm_t Sregsaved; // mask of registers not affected by this func | |
116 | |
117 char Sident[35]; // identifier string (dynamic array) | |
118 // (the size is for static Symbols) | |
119 | |
120 bool needThis() // true if symbol needs a 'this' pointer | |
121 { | |
122 assert(false); | |
123 } | |
124 } | |
125 | |
126 void dumpSymbol(Symbol* foo) | |
127 { | |
128 foreach (a, b; foo.tupleof) | |
129 { | |
130 static if (typeof(foo.tupleof[a]).stringof != "char[35u]") { | |
131 std.stdio.writeln(foo.tupleof[a].stringof, " ", cast(char*)&foo.tupleof[a] - cast(char*)foo, " = ", cast(int)foo.tupleof[a]); | |
132 //std.stdio.writeln("printf(\"", foo.tupleof[a].stringof, " %d = %d\\n\",(char*)(&", foo.tupleof[a].stringof, ")-(char*)foo, ", foo.tupleof[a].stringof, ");"); | |
133 } | |
134 } | |
135 | |
136 std.stdio.writefln("(*foo).Sclass %d = %d", (cast(char*)&foo.Sclass - cast(char*)foo), cast(int)foo.Sclass); | |
137 //std.stdio.writeln("printf(\"(*foo).Sclass %d %d\\n\", ((char*)&foo->Sclass - (char*)foo), (int)foo->Sclass);"); | |
138 } | |
139 | |
140 /+ | |
141 struct Symbol | |
142 { | |
143 debug { | |
144 ushort id; | |
145 ///#define IDsymbol 0x5678 | |
146 ///#define symbol_debug(s) assert((s)->id == IDsymbol) | |
147 ///#define class_debug(s) assert((s)->id == IDsymbol) | |
148 } else { | |
149 ///#define symbol_debug(s) | |
150 ///#define class_debug(s) | |
151 } | |
152 | |
153 Symbol* Sl; | |
154 Symbol* Sr; // left, right child | |
155 | |
156 version (TX86) { | |
157 Symbol *Snext; // next in threaded list | |
158 } | |
159 dt_t* Sdt; // variables: initializer | |
160 type* Stype; // type of Symbol | |
161 | |
162 auto ty() { | |
163 assert(false); | |
164 //return Stype.Tty; | |
165 } | |
166 | |
167 auto Senumlist() | |
168 { | |
169 return Senum.SEenumlist; | |
170 } | |
171 | |
172 union // variants for different Symbol types | |
173 { | |
174 enum_t* Senum; // SCenum | |
175 struct | |
176 { | |
177 func_t* Sfunc; // tyfunc | |
178 list_t Spath1; // SCfuncalias member functions: same as Spath | |
179 // and in same position | |
180 // SCadl: list of associated functions for ADL lookup | |
181 } | |
182 struct // SClabel | |
183 { | |
184 int Slabel; // TRUE if label was defined | |
185 block* Slabelblk_; // label block | |
186 } | |
187 | |
188 version (TX86) { | |
189 struct // SClinkage | |
190 { | |
191 long Slinkage; // tym linkage bits | |
192 uint Smangle; | |
193 } | |
194 } else { | |
195 long Slinkage; // SClinkage, tym linkage bits | |
196 } | |
197 | |
198 struct | |
199 { | |
200 char Sbit; // SCfield: bit position of start of bit field | |
201 char Swidth; // SCfield: width in bits of bit field | |
202 version (TX86) { | |
203 targ_size_t Smemoff; // SCmember,SCfield: offset from start of struct | |
204 } | |
205 } | |
206 | |
207 elem* Svalue; /* SFLvalue: value of const | |
208 SFLdtorexp: for objects with destructor, | |
209 conditional expression to precede dtor call | |
210 */ | |
211 struct_t* Sstruct; // SCstruct | |
212 | |
213 template_t* Stemplate; // SCtemplate | |
214 | |
215 version (SCPP) { | |
216 struct // SCnamespace | |
217 { | |
218 Symbol* Snameroot; // the Symbol table for the namespace | |
219 list_t Susing; // other namespaces from using-directives | |
220 } | |
221 struct | |
222 { | |
223 Symbol* Smemalias; // SCalias: pointer to Symbol to use instead | |
224 // (generated by using-declarations and | |
225 // namespace-alias-definitions) | |
226 // SCmemalias: pointer to member of base class | |
227 // to use instead (using-declarations) | |
228 symlist_t Spath; // SCmemalias: path of classes to get to base | |
229 // class of which Salias is a member | |
230 } | |
231 } | |
232 | |
233 version (TX86) { | |
234 Symbol* Simport; // SCextern: if dllimport Symbol, this is the | |
235 // Symbol it was imported from | |
236 } | |
237 ubyte Spreg; // SCfastpar: register parameter is passed in | |
238 } | |
239 | |
240 version (SCPP_OR_MARS) { | |
241 Symbol* Sscope; // enclosing scope (could be struct tag, | |
242 // enclosing inline function for statics, | |
243 // or namespace) | |
244 //#define isclassmember(s) ((s)->Sscope && (s)->Sscope->Sclass == SCstruct) | |
245 } | |
246 | |
247 version (SCPP) { | |
248 Symbol* Scover; // if there is a tag name and a regular name | |
249 // of the same identifier, Scover is the tag | |
250 // Scover can be SCstruct, SCenum, SCtemplate | |
251 // or an SCalias to them. | |
252 //#define isscover(s) ((s)->Sclass == SCstruct || (s)->Sclass == SCenum || (s)->Sclass == SCtemplate) | |
253 uint Ssequence; // sequence number (used for 2 level lookup) | |
254 // also used as 'parameter number' for SCTtemparg | |
255 } else version (MARS) { | |
256 const(char)* prettyIdent; // the symbol identifer as the user sees it | |
257 } else version (AUTONEST) { | |
258 ubyte Spush; // # of pushes followed by # of | |
259 ubyte Spop; // pops of scope level | |
260 } | |
261 | |
262 version (ELFOBJ_OR_MACHOBJ) { | |
263 int obj_si; // Symbol index of coff or elf symbol | |
264 uint dwarf_off; // offset into .debug section | |
265 targ_size_t code_off; // rel. offset from start of block where var is initialized | |
266 targ_size_t last_off; // last offset using var | |
267 } | |
268 | |
269 version (TARGET_OSX) { | |
270 targ_size_t Slocalgotoffset; | |
271 } | |
272 | |
273 SC Sclass; // storage class (SCxxxx) | |
274 char Sfl; // flavor (FLxxxx) | |
275 SYMFLGS Sflags; // flag bits (SFLxxxx) | |
276 /// #define SFLmark 0x08 // temporary marker | |
277 /// #define SFLvalue 0x01 // Svalue contains const expression | |
278 /// #define SFLimplem 0x02 // if seen implementation of Symbol | |
279 // (function body for functions, | |
280 // initializer for variables) | |
281 /// #define SFLdouble 0x02 // SCregpar or SCparameter, where float | |
282 // is really passed as a double | |
283 /// #define SFLfree 0x04 // if we can symbol_free() a Symbol in | |
284 // a Symbol table[] | |
285 /// #define SFLexit 0x10 // tyfunc: function does not return | |
286 // (ex: exit,abort,_assert,longjmp) | |
287 /// #define SFLtrue 0x200 // value of Symbol != 0 | |
288 /// #define SFLreplace SFLmark // variable gets replaced in inline expansion | |
289 /// #define SFLskipinit 0x10000 // SCfield, SCmember: initializer is skipped | |
290 /// #define SFLnodebug 0x20000 // don't generate debug info | |
291 /// #define SFLwasstatic 0x800000 // was an uninitialized static | |
292 /// #define SFLweak 0x1000000 // resolve to NULL if not found | |
293 | |
294 // CPP | |
295 /// #define SFLnodtor 0x10 // set if destructor for Symbol is already called | |
296 /// #define SFLdtorexp 0x80 // Svalue has expression to tack onto dtor | |
297 /// #define SFLmutable 0x100000 // SCmember or SCfield is mutable | |
298 /// #define SFLdyninit 0x200000 // symbol has dynamic initializer | |
299 /// #define SFLtmp 0x400000 // symbol is a generated temporary | |
300 version (XXX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS | |
301 ///#define SFLthunk 0x40000 // symbol is temporary for thunk | |
302 } | |
303 | |
304 // Possible values for protection bits | |
305 /// #define SFLprivate 0x60 | |
306 /// #define SFLprotected 0x40 | |
307 /// #define SFLpublic 0x20 | |
308 /// #define SFLnone 0x00 | |
309 /// #define SFLpmask 0x60 // mask for the protection bits | |
310 version (VEC_VTBL_LIST) { | |
311 /// #define SFLvtbl 0x2000 // Symbol is a vtable or vbtable | |
312 } | |
313 | |
314 // OPTIMIZER and CODGEN | |
315 /// #define GTregcand 0x100 // if Symbol is a register candidate | |
316 /// #define SFLdead 0x800 // this variable is dead | |
317 | |
318 // OPTIMIZER only | |
319 /// #define SFLunambig 0x400 // only accessible by unambiguous reference, | |
320 // i.e. cannot be addressed via pointer | |
321 // (GTregcand is a subset of this) | |
322 // P.S. code generator turns off this | |
323 // flag if any reads are done from it. | |
324 // This is to eliminate stores to it | |
325 // that are never read. | |
326 /// #define SFLlivexit 0x1000 // live on exit from function | |
327 /// #define SFLnotbasiciv 0x4000 // not a basic induction variable | |
328 /// #define SFLnord SFLdouble // SCauto,SCregister,SCtmp: disallow redundant warnings | |
329 | |
330 // CODGEN only | |
331 /// #define GTtried SFLmark // tried to place in register | |
332 /// #define GTbyte 0x8000 // variable is sometimes accessed as | |
333 /// #define SFLread 0x40000 // variable is actually read from | |
334 // (to eliminate dead stores) | |
335 /// #define SFLspill 0x80000 // only in register part of the time | |
336 | |
337 vec_t Srange; // live range, if any | |
338 vec_t Slvreg; // when symbol is in register | |
339 targ_size_t Ssize; // tyfunc: size of function | |
340 targ_size_t Soffset; // variables: offset of Symbol in its storage class | |
341 version (TARGET_MAC) { | |
342 ///#define Smemoff Soffset | |
343 } | |
344 | |
345 // CPP || OPTIMIZER | |
346 SYMIDX Ssymnum; // Symbol number (index into globsym.tab[]) | |
347 // SCauto,SCparameter,SCtmp,SCregpar,SCregister | |
348 // CODGEN | |
349 version (TX86) { | |
350 short Sseg; // segment index | |
351 } | |
352 int Sweight; // usage count, the higher the number, | |
353 // the more worthwhile it is to put in | |
354 // a register | |
355 union | |
356 { | |
357 uint Sxtrnnum; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1) | |
358 uint Stypidx; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index | |
359 struct | |
360 { | |
361 ubyte Sreglsw; | |
362 ubyte Sregmsw; | |
363 regm_t Sregm; // mask of registers | |
364 } // SCregister,SCregpar,SCpseudo: register number | |
365 } | |
366 | |
367 version (TX86) { | |
368 regm_t Sregsaved; // mask of registers not affected by this func | |
369 } | |
370 | |
371 version (SOURCE_4SYMS) { | |
372 Srcpos Ssrcpos; // file position for definition | |
373 } | |
374 // Target Additions | |
375 /// TARGET_structSYMBOL | |
376 version (TX86) { | |
377 char Sident[SYM_PREDEF_SZ]; // identifier string (dynamic array) | |
378 // (the size is for static Symbols) | |
379 } else { | |
380 long[0] Sident; // identifier string (dynamic array) as a str4 | |
381 } | |
382 | |
383 bool needThis() // true if symbol needs a 'this' pointer | |
384 { | |
385 assert(false); | |
386 } | |
387 } | |
388 +/ |