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