Mercurial > projects > ddmd
annotate dmd/TypeQualified.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.TypeQualified; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Type; |
5 import dmd.Import; | |
73 | 6 import dmd.DsymbolExp; |
0 | 7 import dmd.TypeExp; |
8 import dmd.DotIdExp; | |
9 import dmd.VarDeclaration; | |
10 import dmd.EnumMember; | |
11 import dmd.TupleDeclaration; | |
12 import dmd.Id; | |
13 import dmd.VarExp; | |
14 import dmd.TemplateInstance; | |
15 import dmd.Loc; | |
16 import dmd.Array; | |
17 import dmd.TY; | |
18 import dmd.Identifier; | |
19 import dmd.OutBuffer; | |
20 import dmd.HdrGenState; | |
21 import dmd.Scope; | |
22 import dmd.Dsymbol; | |
23 import dmd.DYNCAST; | |
24 import dmd.Expression; | |
135 | 25 import dmd.FuncDeclaration; |
0 | 26 import dmd.Util; |
27 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
28 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
29 |
0 | 30 class TypeQualified : Type |
31 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
32 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
33 |
0 | 34 Loc loc; |
35 Array idents; // array of Identifier's representing ident.ident.ident etc. | |
36 | |
37 this(TY ty, Loc loc) | |
38 { | |
178 | 39 register(); |
0 | 40 super(ty); |
41 this.loc = loc; | |
42 | |
43 idents = new Array(); | |
44 } | |
45 | |
46 void syntaxCopyHelper(TypeQualified t) | |
47 { | |
48 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars()); | |
49 idents.setDim(t.idents.dim); | |
50 for (int i = 0; i < idents.dim; i++) | |
51 { | |
52 | 52 Object o = cast(Object)t.idents.data[i]; |
53 if (TemplateInstance ti = cast(TemplateInstance)o) | |
0 | 54 { |
52 | 55 o = ti.syntaxCopy(null); |
0 | 56 } |
57 | |
52 | 58 idents.data[i] = cast(void*)o; |
0 | 59 } |
60 } | |
61 | |
52 | 62 void addIdent(Object ident) |
0 | 63 { |
56 | 64 assert(ident !is null); |
0 | 65 idents.push(cast(void*)ident); |
66 } | |
67 | |
68 void toCBuffer2Helper(OutBuffer buf, HdrGenState* hgs) | |
69 { | |
70 int i; | |
71 | |
72 for (i = 0; i < idents.dim; i++) | |
73 { | |
74 Identifier id = cast(Identifier)idents.data[i]; | |
75 buf.writeByte('.'); | |
76 | |
77 if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL) | |
78 { | |
79 TemplateInstance ti = cast(TemplateInstance)id; | |
80 ti.toCBuffer(buf, hgs); | |
81 } else { | |
82 buf.writestring(id.toChars()); | |
83 } | |
84 } | |
85 } | |
86 | |
72 | 87 override ulong size(Loc loc) |
0 | 88 { |
89 assert(false); | |
90 } | |
91 | |
92 /************************************* | |
93 * Takes an array of Identifiers and figures out if | |
94 * it represents a Type or an Expression. | |
95 * Output: | |
96 * if expression, *pe is set | |
97 * if type, *pt is set | |
98 */ | |
99 void resolveHelper(Loc loc, Scope sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps) | |
100 { | |
101 VarDeclaration v; | |
135 | 102 FuncDeclaration fd; |
0 | 103 EnumMember em; |
104 TupleDeclaration td; | |
105 Expression e; | |
106 | |
107 static if (false) { | |
108 printf("TypeQualified.resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); | |
109 if (scopesym) | |
110 printf("\tscopesym = '%s'\n", scopesym.toChars()); | |
111 } | |
112 *pe = null; | |
113 *pt = null; | |
114 *ps = null; | |
115 if (s) | |
116 { | |
117 //printf("\t1: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); | |
118 s.checkDeprecated(loc, sc); // check for deprecated aliases | |
119 s = s.toAlias(); | |
120 //printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); | |
121 for (int i = 0; i < idents.dim; i++) | |
122 { | |
56 | 123 Object o = cast(Object)idents.data[i]; |
124 | |
125 Dsymbol sm = s.searchX(loc, sc, o); | |
126 Identifier id = cast(Identifier)o; | |
0 | 127 //printf("\t3: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); |
128 //printf("\tgetType = '%s'\n", s.getType().toChars()); | |
129 if (!sm) | |
130 { | |
131 Type t; | |
132 | |
133 v = s.isVarDeclaration(); | |
134 if (v && id == Id.length) | |
135 { | |
136 e = v.getConstInitializer(); | |
137 if (!e) | |
138 e = new VarExp(loc, v); | |
139 t = e.type; | |
140 if (!t) | |
141 goto Lerror; | |
142 goto L3; | |
143 } | |
73 | 144 else if (v && id == Id.stringof_) |
145 { | |
146 e = new DsymbolExp(loc, s, 0); | |
147 do | |
148 { | |
149 id = cast(Identifier)idents.data[i]; | |
150 e = new DotIdExp(loc, e, id); | |
151 } while (++i < idents.dim); | |
152 e = e.semantic(sc); | |
153 *pe = e; | |
154 return; | |
155 } | |
156 | |
0 | 157 t = s.getType(); |
158 if (!t && s.isDeclaration()) | |
159 t = s.isDeclaration().type; | |
160 if (t) | |
161 { | |
162 sm = t.toDsymbol(sc); | |
163 if (sm) | |
164 { sm = sm.search(loc, id, 0); | |
165 if (sm) | |
166 goto L2; | |
167 } | |
168 //e = t.getProperty(loc, id); | |
169 e = new TypeExp(loc, t); | |
170 e = t.dotExp(sc, e, id); | |
171 i++; | |
172 L3: | |
173 for (; i < idents.dim; i++) | |
174 { | |
175 id = cast(Identifier)idents.data[i]; | |
176 //printf("e: '%s', id: '%s', type = %p\n", e.toChars(), id.toChars(), e.type); | |
135 | 177 if (id == Id.offsetof || !e.type) |
0 | 178 { e = new DotIdExp(e.loc, e, id); |
179 e = e.semantic(sc); | |
180 } | |
181 else | |
182 e = e.type.dotExp(sc, e, id); | |
183 } | |
184 *pe = e; | |
185 } | |
186 else | |
187 Lerror: | |
188 error(loc, "identifier '%s' of '%s' is not defined", id.toChars(), toChars()); | |
189 return; | |
190 } | |
191 L2: | |
192 s = sm.toAlias(); | |
193 } | |
194 | |
195 v = s.isVarDeclaration(); | |
196 if (v) | |
197 { | |
135 | 198 *pe = new VarExp(loc, v); |
0 | 199 return; |
200 } | |
135 | 201 //#if 0 |
202 // fd = s->isFuncDeclaration(); | |
203 // if (fd) | |
204 // { | |
205 // *pe = new DsymbolExp(loc, fd, 1); | |
206 // return; | |
207 // } | |
208 //#endif | |
0 | 209 em = s.isEnumMember(); |
210 if (em) | |
211 { | |
212 // It's not a type, it's an expression | |
213 *pe = em.value.copy(); | |
214 return; | |
215 } | |
216 | |
217 L1: | |
218 Type t = s.getType(); | |
219 if (!t) | |
220 { | |
221 // If the symbol is an import, try looking inside the import | |
222 Import si; | |
223 | |
224 si = s.isImport(); | |
225 if (si) | |
226 { | |
227 s = si.search(loc, s.ident, 0); | |
228 if (s && s != si) | |
229 goto L1; | |
230 s = si; | |
231 } | |
232 *ps = s; | |
233 return; | |
234 } | |
235 if (t.ty == TY.Tinstance && t != this && !t.deco) | |
236 { | |
237 error(loc, "forward reference to '%s'", t.toChars()); | |
238 return; | |
239 } | |
240 | |
241 if (t != this) | |
242 { | |
243 if (t.reliesOnTident()) | |
244 { | |
73 | 245 if (s.scope_) |
246 t = t.semantic(loc, s.scope_); | |
247 else | |
0 | 248 { |
73 | 249 /* Attempt to find correct scope in which to evaluate t. |
250 * Not sure if this is right or not, or if we should just | |
251 * give forward reference error if s.scope is not set. | |
252 */ | |
253 for (Scope scx = sc; 1; scx = scx.enclosing) | |
254 { | |
255 if (!scx) | |
256 { | |
257 error(loc, "forward reference to '%s'", t.toChars()); | |
258 return; | |
259 } | |
260 if (scx.scopesym == scopesym) | |
261 { | |
262 t = t.semantic(loc, scx); | |
263 break; | |
264 } | |
0 | 265 } |
266 } | |
73 | 267 |
0 | 268 } |
269 } | |
270 if (t.ty == TY.Ttuple) | |
271 *pt = t; | |
272 else | |
273 *pt = t.merge(); | |
274 } | |
275 if (!s) | |
276 { | |
277 error(loc, "identifier '%s' is not defined", toChars()); | |
278 } | |
279 } | |
72 | 280 } |