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