0
|
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 +/ |