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