0
|
1 module dmd.TypeDelegate;
|
|
2
|
114
|
3 import dmd.common;
|
0
|
4 import dmd.Type;
|
|
5 import dmd.TypeNext;
|
|
6 import dmd.MOD;
|
|
7 import dmd.OutBuffer;
|
|
8 import dmd.Id;
|
|
9 import dmd.AddExp;
|
|
10 import dmd.PtrExp;
|
|
11 import dmd.IntegerExp;
|
96
|
12 import dmd.MATCH;
|
0
|
13 import dmd.NullExp;
|
|
14 import dmd.TypeFunction;
|
|
15 import dmd.HdrGenState;
|
|
16 import dmd.Expression;
|
|
17 import dmd.Identifier;
|
|
18 import dmd.CppMangleState;
|
|
19 import dmd.Argument;
|
|
20 import dmd.Loc;
|
|
21 import dmd.Scope;
|
|
22 import dmd.TypeInfoDeclaration;
|
|
23 import dmd.TypeInfoDelegateDeclaration;
|
|
24 import dmd.TY;
|
|
25 import dmd.Global;
|
|
26
|
|
27 import dmd.backend.TYPE;
|
|
28 import dmd.backend.Symbol;
|
|
29 import dmd.backend.Classsym;
|
|
30 import dmd.backend.TYM;
|
|
31 import dmd.backend.SC;
|
|
32 import dmd.backend.Util;
|
|
33 import dmd.backend.LIST;
|
|
34
|
|
35 class TypeDelegate : TypeNext
|
|
36 {
|
|
37 // .next is a TypeFunction
|
|
38
|
|
39 this(Type t)
|
|
40 {
|
|
41 super(TY.Tfunction, t);
|
|
42 ty = TY.Tdelegate;
|
|
43 }
|
|
44
|
|
45 version (DumbClone) {
|
|
46 } else {
|
|
47 Type clone()
|
|
48 {
|
|
49 assert(false);
|
|
50 }
|
|
51 }
|
72
|
52 override Type syntaxCopy()
|
0
|
53 {
|
|
54 Type t = next.syntaxCopy();
|
|
55 if (t == next)
|
|
56 t = this;
|
|
57 else
|
|
58 {
|
|
59 t = new TypeDelegate(t);
|
|
60 t.mod = mod;
|
|
61 }
|
|
62 return t;
|
|
63 }
|
|
64
|
72
|
65 override Type semantic(Loc loc, Scope sc)
|
0
|
66 {
|
|
67 if (deco) // if semantic() already run
|
|
68 {
|
|
69 //printf("already done\n");
|
|
70 return this;
|
|
71 }
|
|
72
|
|
73 next = next.semantic(loc, sc);
|
|
74 return merge();
|
|
75 }
|
|
76
|
72
|
77 override ulong size(Loc loc)
|
0
|
78 {
|
|
79 return PTRSIZE * 2;
|
|
80 }
|
|
81
|
96
|
82 MATCH implicitConvTo(Type to)
|
|
83 {
|
|
84 //writef("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
|
|
85 //writef("from: %s\n", toChars());
|
|
86 //writef("to : %s\n", to.toChars());
|
|
87 if (this == to)
|
|
88 return MATCHexact;
|
|
89 static if (false) // not allowing covariant conversions because it interferes with overriding
|
|
90 {
|
|
91 if (to.ty == Tdelegate && this.nextOf().covariant(to.nextOf()) == 1)
|
|
92 return MATCHconvert;
|
|
93 }
|
|
94 return MATCHnomatch;
|
|
95 }
|
|
96
|
72
|
97 override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
|
0
|
98 {
|
|
99 if (mod != this.mod)
|
|
100 {
|
|
101 toCBuffer3(buf, hgs, mod);
|
|
102 return;
|
|
103 }
|
|
104 TypeFunction tf = cast(TypeFunction)next;
|
|
105
|
|
106 tf.next.toCBuffer2(buf, hgs, MODundefined);
|
|
107 buf.writestring(" delegate");
|
|
108 Argument.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
|
|
109 }
|
|
110
|
72
|
111 override Expression defaultInit(Loc loc)
|
0
|
112 {
|
|
113 version (LOGDEFAULTINIT) {
|
|
114 printf("TypeDelegate.defaultInit() '%s'\n", toChars());
|
|
115 }
|
|
116 Expression e;
|
|
117 e = new NullExp(loc);
|
|
118 e.type = this;
|
|
119 return e;
|
|
120 }
|
|
121
|
72
|
122 override bool isZeroInit(Loc loc)
|
0
|
123 {
|
|
124 return true;
|
|
125 }
|
|
126
|
72
|
127 override bool checkBoolean()
|
0
|
128 {
|
|
129 return true;
|
|
130 }
|
|
131
|
72
|
132 override TypeInfoDeclaration getTypeInfoDeclaration()
|
0
|
133 {
|
|
134 return new TypeInfoDelegateDeclaration(this);
|
|
135 }
|
|
136
|
72
|
137 override Expression dotExp(Scope sc, Expression e, Identifier ident)
|
0
|
138 {
|
|
139 version (LOGDOTEXP) {
|
|
140 printf("TypeDelegate.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
|
|
141 }
|
|
142 if (ident == Id.ptr)
|
|
143 {
|
|
144 e.type = tvoidptr;
|
|
145 return e;
|
|
146 }
|
|
147 else if (ident == Id.funcptr)
|
|
148 {
|
|
149 e = e.addressOf(sc);
|
|
150 e.type = tvoidptr;
|
|
151 e = new AddExp(e.loc, e, new IntegerExp(PTRSIZE));
|
|
152 e.type = tvoidptr;
|
|
153 e = new PtrExp(e.loc, e);
|
|
154 e.type = next.pointerTo();
|
|
155 return e;
|
|
156 }
|
|
157 else
|
|
158 {
|
|
159 e = Type.dotExp(sc, e, ident);
|
|
160 }
|
|
161 return e;
|
|
162 }
|
|
163
|
72
|
164 override bool hasPointers()
|
0
|
165 {
|
|
166 return true;
|
|
167 }
|
|
168
|
|
169 version (CPP_MANGLE) {
|
|
170 void toCppMangle(OutBuffer buf, CppMangleState* cms)
|
|
171 {
|
|
172 assert(false);
|
|
173 }
|
|
174 }
|
|
175
|
72
|
176 override type* toCtype()
|
0
|
177 {
|
|
178 type* t;
|
|
179
|
|
180 if (ctype)
|
|
181 return ctype;
|
|
182
|
|
183 if (0 && global.params.symdebug)
|
|
184 {
|
|
185 /* A delegate consists of:
|
|
186 * _Delegate { void* frameptr; Function *funcptr; }
|
|
187 */
|
|
188
|
|
189 static Symbol* s;
|
|
190
|
|
191 if (!s)
|
|
192 {
|
|
193 s = symbol_calloc("_Delegate");
|
|
194 s.Sclass = SC.SCstruct;
|
|
195 s.Sstruct = struct_calloc();
|
|
196 s.Sstruct.Sflags |= 0; /// huh?
|
|
197 s.Sstruct.Salignsize = alignsize();
|
|
198 s.Sstruct.Sstructalign = cast(ubyte)global.structalign;
|
|
199 s.Sstruct.Sstructsize = cast(uint)size(Loc(0));
|
|
200 slist_add(s);
|
|
201
|
|
202 Symbol* s1 = symbol_name("frameptr", SC.SCmember, Type.tvoidptr.toCtype());
|
|
203 list_append(&s.Sstruct.Sfldlst, s1);
|
|
204
|
|
205 Symbol* s2 = symbol_name("funcptr", SC.SCmember, Type.tvoidptr.toCtype());
|
|
206 s2.Smemoff = cast(uint)Type.tvoidptr.size();
|
|
207 list_append(&s.Sstruct.Sfldlst, s2);
|
|
208 }
|
|
209
|
|
210 t = type_alloc(TYM.TYstruct);
|
|
211 t.Ttag = cast(Classsym*)s; // structure tag name
|
|
212 t.Tcount++;
|
|
213 s.Stype = t;
|
|
214 }
|
|
215 else
|
|
216 {
|
|
217 if (global.params.symdebug == 1)
|
|
218 {
|
|
219 // Generate D symbolic debug info, rather than C
|
|
220 t = type_allocn(TYM.TYdelegate, next.toCtype());
|
|
221 }
|
|
222 else
|
|
223 t = type_fake(TYM.TYdelegate);
|
|
224 }
|
|
225
|
|
226 t.Tcount++;
|
|
227 ctype = t;
|
|
228 return t;
|
|
229 }
|
72
|
230 }
|