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