0
|
1 module dmd.TypeNext;
|
|
2
|
114
|
3 import dmd.common;
|
0
|
4 import dmd.Type;
|
96
|
5 import dmd.TypeAArray;
|
0
|
6 import dmd.TY;
|
|
7 import dmd.OutBuffer;
|
|
8 import dmd.Loc;
|
|
9 import dmd.Scope;
|
|
10 import dmd.MATCH;
|
|
11 import dmd.MOD;
|
|
12
|
|
13 class TypeNext : Type
|
|
14 {
|
|
15 Type next;
|
|
16
|
|
17 this(TY ty, Type next)
|
|
18 {
|
|
19 super(ty);
|
|
20 this.next = next;
|
|
21 }
|
|
22 version (DumbClone) {
|
|
23 } else {
|
|
24 final TypeNext cloneTo(TypeNext t)
|
|
25 {
|
|
26 super.cloneTo(t);
|
|
27 return t;
|
|
28 }
|
|
29
|
|
30 TypeNext clone()
|
|
31 {
|
|
32 assert(this.classinfo == TypeNext.classinfo);
|
|
33 return cloneTo(new TypeNext(ty, next));
|
|
34 }
|
|
35 }
|
72
|
36 override void toDecoBuffer(OutBuffer buf, int flag)
|
0
|
37 {
|
|
38 super.toDecoBuffer(buf, flag);
|
|
39 assert(next !is this);
|
|
40 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this.ty, next, next.ty);
|
|
41 next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
|
|
42 }
|
|
43
|
72
|
44 override void checkDeprecated(Loc loc, Scope sc)
|
0
|
45 {
|
|
46 Type.checkDeprecated(loc, sc);
|
|
47 if (next) // next can be null if TypeFunction and auto return type
|
|
48 next.checkDeprecated(loc, sc);
|
|
49 }
|
|
50
|
72
|
51 override Type reliesOnTident()
|
0
|
52 {
|
|
53 return next.reliesOnTident();
|
|
54 }
|
|
55
|
135
|
56 override int hasWild()
|
|
57 {
|
|
58 return mod == MOD.MODwild || next.hasWild();
|
|
59 }
|
|
60
|
|
61 /***************************************
|
|
62 * Return MOD bits matching argument type (targ) to wild parameter type (this).
|
|
63 */
|
|
64
|
|
65 override uint wildMatch(Type targ)
|
|
66 {
|
|
67 uint mod;
|
|
68
|
|
69 Type tb = targ.nextOf();
|
|
70 if (!tb)
|
|
71 return 0;
|
|
72 tb = tb.toBasetype();
|
|
73 if (tb.isMutable())
|
|
74 mod = MOD.MODmutable;
|
|
75 else if (tb.isConst() || tb.isWild())
|
|
76 return MOD.MODconst;
|
|
77 else if (tb.isImmutable())
|
|
78 mod = MOD.MODimmutable;
|
|
79 else
|
|
80 assert(0);
|
|
81 mod |= next.wildMatch(tb);
|
|
82 return mod;
|
|
83 }
|
|
84
|
72
|
85 override Type nextOf()
|
0
|
86 {
|
|
87 return next;
|
|
88 }
|
|
89
|
72
|
90 override Type makeConst()
|
0
|
91 {
|
|
92 //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
|
|
93 if (cto)
|
|
94 {
|
|
95 assert(cto.mod == MOD.MODconst);
|
|
96 return cto;
|
|
97 }
|
|
98
|
|
99 TypeNext t = cast(TypeNext)super.makeConst();
|
|
100 if (ty != TY.Tfunction && ty != TY.Tdelegate &&
|
|
101 (next.deco || next.ty == TY.Tfunction) &&
|
135
|
102 !next.isImmutable() && !next.isConst())
|
0
|
103 {
|
|
104 if (next.isShared())
|
|
105 t.next = next.sharedConstOf();
|
|
106 else
|
|
107 t.next = next.constOf();
|
|
108 }
|
96
|
109 if (ty == Taarray)
|
|
110 {
|
|
111 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
112 }
|
|
113 //writef("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
|
0
|
114 return t;
|
|
115 }
|
|
116
|
72
|
117 override Type makeInvariant()
|
0
|
118 {
|
|
119 //printf("TypeNext::makeInvariant() %s\n", toChars());
|
|
120 if (ito)
|
|
121 {
|
135
|
122 assert(ito.isImmutable());
|
0
|
123 return ito;
|
|
124 }
|
|
125 TypeNext t = cast(TypeNext)Type.makeInvariant();
|
135
|
126 if (ty != TY.Tfunction && ty != TY.Tdelegate && (next.deco || next.ty == TY.Tfunction) && !next.isImmutable())
|
0
|
127 {
|
|
128 t.next = next.invariantOf();
|
|
129 }
|
96
|
130 if (ty == Taarray)
|
|
131 {
|
|
132 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
133 }
|
0
|
134 return t;
|
|
135 }
|
|
136
|
72
|
137 override Type makeShared()
|
0
|
138 {
|
|
139 //printf("TypeNext::makeShared() %s\n", toChars());
|
|
140 if (sto)
|
|
141 {
|
|
142 assert(sto.mod == MODshared);
|
|
143 return sto;
|
|
144 }
|
|
145 TypeNext t = cast(TypeNext)Type.makeShared();
|
|
146 if (ty != Tfunction && ty != Tdelegate &&
|
|
147 (next.deco || next.ty == Tfunction) &&
|
135
|
148 !next.isImmutable() && !next.isShared())
|
0
|
149 {
|
135
|
150 if (next.isConst() || next.isWild())
|
0
|
151 t.next = next.sharedConstOf();
|
|
152 else
|
|
153 t.next = next.sharedOf();
|
|
154 }
|
96
|
155 if (ty == Taarray)
|
|
156 {
|
|
157 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
158 }
|
|
159 //writef("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
|
0
|
160 return t;
|
|
161 }
|
|
162
|
96
|
163 override Type makeSharedConst()
|
0
|
164 {
|
96
|
165 //printf("TypeNext::makeSharedConst() %s\n", toChars());
|
|
166 if (scto)
|
|
167 {
|
|
168 assert(scto.mod == (MODshared | MODconst));
|
|
169 return scto;
|
|
170 }
|
|
171 TypeNext t = cast(TypeNext) Type.makeSharedConst();
|
|
172 if (ty != Tfunction && ty != Tdelegate &&
|
|
173 (next.deco || next.ty == Tfunction) &&
|
135
|
174 !next.isImmutable() && !next.isSharedConst())
|
96
|
175 {
|
|
176 t.next = next.sharedConstOf();
|
|
177 }
|
|
178 if (ty == Taarray)
|
|
179 {
|
|
180 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
181 }
|
|
182 // writef("TypeNext::makeSharedConst() returns %p, %s\n", t, t.toChars());
|
|
183 return t;
|
0
|
184 }
|
|
185
|
135
|
186 override Type makeWild()
|
|
187 {
|
|
188 //printf("TypeNext::makeWild() %s\n", toChars());
|
|
189 if (wto)
|
|
190 {
|
|
191 assert(wto.mod == MODwild);
|
|
192 return wto;
|
|
193 }
|
|
194 auto t = cast(TypeNext)Type.makeWild();
|
|
195 if (ty != TY.Tfunction && ty != TY.Tdelegate &&
|
|
196 (next.deco || next.ty == TY.Tfunction) &&
|
|
197 !next.isImmutable() && !next.isConst() && !next.isWild())
|
|
198 {
|
|
199 if (next.isShared())
|
|
200 t.next = next.sharedWildOf();
|
|
201 else
|
|
202 t.next = next.wildOf();
|
|
203 }
|
|
204 if (ty == TY.Taarray)
|
|
205 {
|
|
206 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
207 }
|
|
208 //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
|
|
209 return t;
|
|
210 }
|
|
211
|
|
212 Type makeSharedWild()
|
|
213 {
|
|
214 //printf("TypeNext::makeSharedWild() %s\n", toChars());
|
|
215 if (swto)
|
|
216 {
|
|
217 assert(swto.isSharedWild());
|
|
218 return swto;
|
|
219 }
|
|
220 auto t = cast(TypeNext)Type.makeSharedWild();
|
|
221 if (ty != TY.Tfunction && ty != TY.Tdelegate &&
|
|
222 (next.deco || next.ty == TY.Tfunction) &&
|
|
223 !next.isImmutable() && !next.isSharedConst())
|
|
224 {
|
|
225 t.next = next.sharedWildOf();
|
|
226 }
|
|
227 if (ty == Taarray)
|
|
228 {
|
|
229 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
230 }
|
|
231 //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
|
|
232 return t;
|
|
233 }
|
|
234
|
|
235 Type makeMutable()
|
|
236 {
|
|
237 //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
|
|
238 auto t = cast(TypeNext)Type.makeMutable();
|
|
239 if (ty != TY.Tfunction && ty != TY.Tdelegate &&
|
|
240 (next.deco || next.ty == TY.Tfunction) &&
|
|
241 next.isWild())
|
|
242 {
|
|
243 t.next = next.mutableOf();
|
|
244 }
|
|
245 if (ty == Taarray)
|
|
246 {
|
|
247 (cast(TypeAArray)t).impl = null; // lazily recompute it
|
|
248 }
|
|
249 //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
|
|
250 return t;
|
|
251 }
|
|
252
|
96
|
253 override MATCH constConv(Type to)
|
0
|
254 {
|
56
|
255 MATCH m = Type.constConv(to);
|
|
256
|
|
257 if (m == MATCHconst && next.constConv((cast(TypeNext)to).next) == MATCHnomatch)
|
|
258 m = MATCHnomatch;
|
|
259 return m;
|
0
|
260 }
|
|
261
|
96
|
262 void transitive()
|
0
|
263 {
|
|
264 /* Invoke transitivity of type attributes
|
|
265 */
|
|
266 next = next.addMod(mod);
|
|
267 }
|
72
|
268 }
|