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