Mercurial > projects > ddmd
annotate dmd/SymbolExp.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | e28b18c23469 |
children | cd48cb899aee |
rev | line source |
---|---|
72 | 1 module dmd.SymbolExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.Declaration; | |
6 import dmd.Loc; | |
7 import dmd.IRState; | |
8 import dmd.TOK; | |
9 import dmd.TY; | |
10 import dmd.Type; | |
11 import dmd.SymOffExp; | |
12 import dmd.FuncDeclaration; | |
13 import dmd.VarDeclaration; | |
14 import dmd.backend.OPER; | |
15 import dmd.backend.TYM; | |
16 import dmd.backend.mTY; | |
17 import dmd.backend.SC; | |
18 import dmd.backend.elem; | |
19 import dmd.backend.Symbol; | |
20 import dmd.backend.Util; | |
21 import dmd.codegen.Util; | |
22 | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
23 version(DMDV2) |
0 | 24 class SymbolExp : Expression |
25 { | |
26 Declaration var; | |
27 | |
73 | 28 bool hasOverloads; |
0 | 29 |
73 | 30 this(Loc loc, TOK op, int size, Declaration var, bool hasOverloads) |
0 | 31 { |
178 | 32 register(); |
72 | 33 super(loc, op, size); |
34 assert(var); | |
35 this.var = var; | |
0 | 36 this.hasOverloads = hasOverloads; |
37 } | |
38 | |
72 | 39 override elem* toElem(IRState* irs) |
0 | 40 { |
72 | 41 Symbol* s; |
42 elem* e; | |
43 tym_t tym; | |
44 Type tb = (op == TOK.TOKsymoff) ? var.type.toBasetype() : type.toBasetype(); | |
45 int offset = (op == TOK.TOKsymoff) ? (cast(SymOffExp)this).offset : 0; | |
46 FuncDeclaration fd; | |
47 VarDeclaration v = var.isVarDeclaration(); | |
48 | |
49 //printf("SymbolExp::toElem('%s') %p\n", toChars(), this); | |
50 //printf("\tparent = '%s'\n", var.parent ? var.parent.toChars() : "null"); | |
51 if (op == TOK.TOKvar && var.needThis()) | |
52 { | |
53 error("need 'this' to access member %s", toChars()); | |
54 return el_long(TYM.TYint, 0); | |
55 } | |
56 s = var.toSymbol(); | |
57 fd = null; | |
58 if (var.toParent2()) | |
59 fd = var.toParent2().isFuncDeclaration(); | |
60 | |
61 int nrvo = 0; | |
62 if (fd && fd.nrvo_can && fd.nrvo_var == var) | |
63 { | |
64 s = fd.shidden; | |
65 nrvo = 1; | |
66 } | |
67 | |
68 if (s.Sclass == SC.SCauto || s.Sclass == SC.SCparameter) | |
69 { | |
70 if (fd && fd != irs.getFunc()) | |
71 { | |
72 // 'var' is a variable in an enclosing function. | |
73 elem* ethis; | |
74 int soffset; | |
75 | |
76 ethis = getEthis(loc, irs, fd); | |
77 ethis = el_una(OPER.OPaddr, TYM.TYnptr, ethis); | |
78 | |
79 if (v && v.offset) | |
80 soffset = v.offset; | |
81 else | |
82 { | |
83 soffset = s.Soffset; | |
84 /* If fd is a non-static member function of a class or struct, | |
85 * then ethis isn't the frame pointer. | |
86 * ethis is the 'this' pointer to the class/struct instance. | |
87 * We must offset it. | |
88 */ | |
89 if (fd.vthis) | |
90 { | |
91 soffset -= fd.vthis.toSymbol().Soffset; | |
92 } | |
93 //printf("\tSoffset = x%x, sthis.Soffset = x%x\n", s.Soffset, irs.sthis.Soffset); | |
94 } | |
95 | |
96 if (!nrvo) | |
97 soffset += offset; | |
98 | |
99 e = el_bin(OPER.OPadd, TYM.TYnptr, ethis, el_long(TYM.TYnptr, soffset)); | |
100 | |
101 if (op == TOK.TOKvar) | |
102 e = el_una(OPER.OPind, TYM.TYnptr, e); | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
103 if (ISREF(var, tb)) |
72 | 104 e = el_una(OPER.OPind, s.ty(), e); |
105 else if (op == TOK.TOKsymoff && nrvo) | |
106 { | |
107 e = el_una(OPER.OPind, TYM.TYnptr, e); | |
108 e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); | |
109 } | |
110 goto L1; | |
111 } | |
112 } | |
113 | |
114 /* If var is a member of a closure | |
115 */ | |
116 if (v && v.offset) | |
117 { | |
118 assert(irs.sclosure); | |
119 e = el_var(irs.sclosure); | |
120 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v.offset)); | |
121 if (op == TOK.TOKvar) | |
122 { | |
123 e = el_una(OPER.OPind, type.totym(), e); | |
124 if (tybasic(e.Ety) == TYM.TYstruct) | |
125 e.Enumbytes = cast(uint)type.size(); | |
126 el_setLoc(e, loc); | |
127 } | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
128 if (ISREF(var, tb)) |
72 | 129 { |
130 e.Ety = TYM.TYnptr; | |
131 e = el_una(OPER.OPind, s.ty(), e); | |
132 } | |
133 else if (op == TOK.TOKsymoff && nrvo) | |
134 { e = el_una(OPER.OPind, TYM.TYnptr, e); | |
135 e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); | |
136 } | |
137 else if (op == TOK.TOKsymoff) | |
138 { | |
139 e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); | |
140 } | |
141 goto L1; | |
142 } | |
143 | |
144 if (s.Sclass == SC.SCauto && s.Ssymnum == -1) | |
145 { | |
146 //printf("\tadding symbol\n"); | |
147 symbol_add(s); | |
148 } | |
149 | |
150 if (var.isImportedSymbol()) | |
151 { | |
152 assert(op == TOK.TOKvar); | |
153 e = el_var(var.toImport()); | |
154 e = el_una(OPER.OPind,s.ty(),e); | |
155 } | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
156 else if (ISREF(var, tb)) |
72 | 157 { |
158 // Static arrays are really passed as pointers to the array | |
159 // Out parameters are really references | |
160 e = el_var(s); | |
161 e.Ety = TYM.TYnptr; | |
162 if (op == TOK.TOKvar) | |
163 e = el_una(OPER.OPind, s.ty(), e); | |
164 else if (offset) | |
165 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); | |
166 } | |
167 else if (op == TOK.TOKvar) | |
168 e = el_var(s); | |
169 else | |
170 { | |
171 e = nrvo ? el_var(s) : el_ptr(s); | |
172 e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); | |
173 } | |
174 L1: | |
175 if (op == TOK.TOKvar) | |
176 { | |
177 if (nrvo) | |
178 { | |
179 e.Ety = TYM.TYnptr; | |
180 e = el_una(OPER.OPind, 0, e); | |
181 } | |
182 if (tb.ty == TY.Tfunction) | |
183 { | |
184 tym = s.Stype.Tty; | |
185 } | |
186 else | |
187 tym = type.totym(); | |
188 e.Ejty = cast(ubyte)tym; | |
189 e.Ety = e.Ejty; | |
190 if (tybasic(tym) == TYM.TYstruct) | |
191 { | |
192 e.Enumbytes = cast(uint)type.size(); | |
193 } | |
194 else if (tybasic(tym) == TYM.TYarray) | |
195 { | |
196 e.Ejty = TYM.TYstruct; | |
197 e.Ety = e.Ejty; | |
198 e.Enumbytes = cast(uint)type.size(); | |
199 } | |
200 } | |
201 el_setLoc(e,loc); | |
0 | 202 return e; |
203 } | |
204 } | |
205 |