Mercurial > projects > ddmd
comparison dmd/TypeDelegate.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 2e2a5c3f943a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
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 } |