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