Mercurial > projects > ddmd
annotate dmd/SymOffExp.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 60bb0fe4563e |
children | af724d3510d7 |
rev | line source |
---|---|
72 | 1 module dmd.SymOffExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.Declaration; | |
6 import dmd.MATCH; | |
7 import dmd.Type; | |
8 import dmd.OutBuffer; | |
9 import dmd.Loc; | |
10 import dmd.Scope; | |
11 import dmd.InlineDoState; | |
12 import dmd.HdrGenState; | |
13 import dmd.backend.dt_t; | |
0 | 14 import dmd.SymbolExp; |
15 import dmd.VarDeclaration; | |
16 import dmd.DelegateExp; | |
17 import dmd.ThisExp; | |
18 import dmd.FuncDeclaration; | |
19 import dmd.IntegerExp; | |
20 import dmd.ErrorExp; | |
72 | 21 import dmd.TY; |
0 | 22 import dmd.TOK; |
135 | 23 import dmd.STC; |
0 | 24 |
25 import dmd.backend.Symbol; | |
26 import dmd.backend.Util; | |
27 import dmd.backend.TYM; | |
72 | 28 |
0 | 29 class SymOffExp : SymbolExp |
30 { | |
31 uint offset; | |
32 | |
73 | 33 this(Loc loc, Declaration var, uint offset, bool hasOverloads = false) |
0 | 34 { |
35 super(loc, TOK.TOKsymoff, SymOffExp.sizeof, var, hasOverloads); | |
36 | |
37 this.offset = offset; | |
38 VarDeclaration v = var.isVarDeclaration(); | |
39 if (v && v.needThis()) | |
40 error("need 'this' for address of %s", v.toChars()); | |
41 } | |
42 | |
72 | 43 override Expression semantic(Scope sc) |
0 | 44 { |
45 version(LOGSEMANTIC) { | |
46 printf("SymOffExp::semantic('%s')\n", toChars()); | |
47 } | |
48 //var.semantic(sc); | |
49 if (!type) | |
50 type = var.type.pointerTo(); | |
51 VarDeclaration v = var.isVarDeclaration(); | |
52 if (v) | |
53 v.checkNestedReference(sc, loc); | |
54 return this; | |
55 } | |
56 | |
72 | 57 override void checkEscape() |
0 | 58 { |
59 VarDeclaration v = var.isVarDeclaration(); | |
60 if (v) | |
61 { | |
135 | 62 if (!v.isDataseg() && !(v.storage_class & (STC.STCref | STC.STCout))) |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
63 { /* BUG: This should be allowed: |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
64 * void foo() |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
65 * { int a; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
66 * int* bar() { return &a; } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
67 * } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
68 */ |
135 | 69 error("escaping reference to local %s", v.toChars()); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
70 } |
0 | 71 } |
72 } | |
73 | |
72 | 74 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 75 { |
76 assert(false); | |
77 } | |
78 | |
72 | 79 override int isConst() |
0 | 80 { |
81 return 2; | |
82 } | |
83 | |
72 | 84 override bool isBool(bool result) |
0 | 85 { |
129 | 86 return result; |
0 | 87 } |
88 | |
72 | 89 override Expression doInline(InlineDoState ids) |
0 | 90 { |
91 int i; | |
92 | |
93 //printf("SymOffExp.doInline(%s)\n", toChars()); | |
94 for (i = 0; i < ids.from.dim; i++) | |
95 { | |
96 if (var is cast(Declaration)ids.from.data[i]) | |
97 { | |
98 SymOffExp se = cast(SymOffExp)copy(); | |
99 | |
100 se.var = cast(Declaration)ids.to.data[i]; | |
101 return se; | |
102 } | |
103 } | |
104 return this; | |
105 } | |
106 | |
72 | 107 override MATCH implicitConvTo(Type t) |
0 | 108 { |
109 static if (false) { | |
110 printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); | |
111 } | |
112 MATCH result = type.implicitConvTo(t); | |
113 //printf("\tresult = %d\n", result); | |
114 | |
115 if (result == MATCHnomatch) | |
116 { | |
117 // Look for pointers to functions where the functions are overloaded. | |
118 FuncDeclaration f; | |
119 | |
120 t = t.toBasetype(); | |
121 if (type.ty == Tpointer && type.nextOf().ty == Tfunction && | |
122 (t.ty == Tpointer || t.ty == Tdelegate) && t.nextOf().ty == Tfunction) | |
123 { | |
124 f = var.isFuncDeclaration(); | |
125 if (f) | |
126 { | |
127 f = f.overloadExactMatch(t.nextOf()); | |
128 if (f) | |
129 { | |
130 if ((t.ty == Tdelegate && (f.needThis() || f.isNested())) || | |
131 (t.ty == Tpointer && !(f.needThis() || f.isNested()))) | |
132 { | |
133 result = MATCHexact; | |
134 } | |
135 } | |
136 } | |
137 } | |
138 } | |
139 //printf("\tresult = %d\n", result); | |
140 return result; | |
141 } | |
142 | |
72 | 143 override Expression castTo(Scope sc, Type t) |
0 | 144 { |
145 static if (false) { | |
146 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); | |
147 } | |
73 | 148 if (type == t && !hasOverloads) |
0 | 149 return this; |
150 | |
151 Expression e; | |
152 Type tb = t.toBasetype(); | |
153 Type typeb = type.toBasetype(); | |
154 | |
155 if (tb != typeb) | |
156 { | |
157 // Look for pointers to functions where the functions are overloaded. | |
158 FuncDeclaration f; | |
159 | |
160 if (hasOverloads && | |
161 typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction && | |
162 (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction) | |
163 { | |
164 f = var.isFuncDeclaration(); | |
165 if (f) | |
166 { | |
167 f = f.overloadExactMatch(tb.nextOf()); | |
168 if (f) | |
169 { | |
170 if (tb.ty == Tdelegate) | |
171 { | |
172 if (f.needThis() && hasThis(sc)) | |
173 { | |
174 e = new DelegateExp(loc, new ThisExp(loc), f); | |
175 e = e.semantic(sc); | |
176 } | |
177 else if (f.isNested()) | |
178 { | |
179 e = new DelegateExp(loc, new IntegerExp(0), f); | |
180 e = e.semantic(sc); | |
181 } | |
182 else if (f.needThis()) | |
183 { | |
184 error("no 'this' to create delegate for %s", f.toChars()); | |
185 e = new ErrorExp(); | |
186 } | |
187 else | |
188 { | |
189 error("cannot cast from function pointer to delegate"); | |
190 e = new ErrorExp(); | |
191 } | |
192 } | |
193 else | |
194 { | |
195 e = new SymOffExp(loc, f, 0); | |
196 e.type = t; | |
197 } | |
198 version (DMDV2) { | |
199 f.tookAddressOf++; | |
200 } | |
201 return e; | |
202 } | |
203 } | |
204 } | |
205 e = Expression.castTo(sc, t); | |
206 } | |
207 else | |
208 { | |
209 e = copy(); | |
210 e.type = t; | |
73 | 211 (cast(SymOffExp)e).hasOverloads = false; |
0 | 212 } |
213 return e; | |
214 } | |
215 | |
72 | 216 override void scanForNestedRef(Scope sc) |
0 | 217 { |
72 | 218 //printf("SymOffExp.scanForNestedRef(%s)\n", toChars()); |
219 VarDeclaration v = var.isVarDeclaration(); | |
220 if (v) | |
64 | 221 v.checkNestedReference(sc, Loc(0)); |
0 | 222 } |
223 | |
72 | 224 override dt_t** toDt(dt_t** pdt) |
0 | 225 { |
226 //printf("SymOffExp.toDt('%s')\n", var.toChars()); | |
227 assert(var); | |
228 if (!(var.isDataseg() || var.isCodeseg()) || | |
229 var.needThis() || | |
230 var.isThreadlocal() | |
231 ) | |
232 { | |
233 debug writef("SymOffExp.toDt()\n"); | |
234 error("non-constant expression %s", toChars()); | |
235 return pdt; | |
236 } | |
237 | |
238 Symbol* s = var.toSymbol(); | |
239 return dtxoff(pdt, s, offset, TYnptr); | |
240 } | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
241 |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
242 static if (false) |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
243 { |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
244 override elem* toElem(IRState* irs) |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
245 { |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
246 assert(false); // this function is #if 0'ed out in dmd |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
247 } |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
248 } |
0 | 249 } |
250 |