comparison dmd/SymOffExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 4290d870944a
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
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;
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;
20 import dmd.TY;
21 import dmd.TOK;
22
23 import dmd.backend.Symbol;
24 import dmd.backend.Util;
25 import dmd.backend.TYM;
26
27 class SymOffExp : SymbolExp
28 {
29 uint offset;
30
31 this(Loc loc, Declaration var, uint offset, int hasOverloads = 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
41 Expression semantic(Scope sc)
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
55 void checkEscape()
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
65 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
66 {
67 assert(false);
68 }
69
70 int isConst()
71 {
72 return 2;
73 }
74
75 bool isBool(bool result)
76 {
77 assert(false);
78 }
79
80 Expression doInline(InlineDoState ids)
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
98 MATCH implicitConvTo(Type t)
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
134 Expression castTo(Scope sc, Type t)
135 {
136 static if (false) {
137 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars());
138 }
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;
202 (cast(SymOffExp)e).hasOverloads = 0;
203 }
204 return e;
205 }
206
207 void scanForNestedRef(Scope sc)
208 {
209 assert(false);
210 }
211
212 dt_t** toDt(dt_t** pdt)
213 {
214 //printf("SymOffExp.toDt('%s')\n", var.toChars());
215 assert(var);
216 if (!(var.isDataseg() || var.isCodeseg()) ||
217 var.needThis() ||
218 var.isThreadlocal()
219 )
220 {
221 debug writef("SymOffExp.toDt()\n");
222 error("non-constant expression %s", toChars());
223 return pdt;
224 }
225
226 Symbol* s = var.toSymbol();
227 return dtxoff(pdt, s, offset, TYnptr);
228 }
229 }
230