Mercurial > projects > ddmd
comparison dmd/ClassDeclaration.d @ 176:fa9a71a9f5a8
Moved all the mutable globals to Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 05:22:45 +0400 |
parents | af724d3510d7 |
children | e3afd1303184 |
comparison
equal
deleted
inserted
replaced
175:94b6033c07f3 | 176:fa9a71a9f5a8 |
---|---|
76 bool visit(FuncDeclaration fd2) | 76 bool visit(FuncDeclaration fd2) |
77 { | 77 { |
78 //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); | 78 //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); |
79 return fd is fd2; | 79 return fd is fd2; |
80 } | 80 } |
81 | 81 |
82 FuncDeclaration fd; | 82 FuncDeclaration fd; |
83 } | 83 } |
84 | 84 |
85 class ClassDeclaration : AggregateDeclaration | 85 class ClassDeclaration : AggregateDeclaration |
86 { | 86 { |
115 int inuse; // to prevent recursive attempts | 115 int inuse; // to prevent recursive attempts |
116 | 116 |
117 this(Loc loc, Identifier id, BaseClasses baseclasses) | 117 this(Loc loc, Identifier id, BaseClasses baseclasses) |
118 { | 118 { |
119 super(loc, id); | 119 super(loc, id); |
120 | 120 |
121 vtbl = new Array(); | 121 vtbl = new Array(); |
122 vtblFinal = new Array(); | 122 vtblFinal = new Array(); |
123 | 123 |
124 enum msg = "only object.d can define this reserved class name"; | 124 enum msg = "only object.d can define this reserved class name"; |
125 | 125 |
126 if (baseclasses) { | 126 if (baseclasses) { |
127 this.baseclasses = baseclasses; | 127 this.baseclasses = baseclasses; |
128 } else { | 128 } else { |
143 | 143 |
144 // BUG: What if this is the wrong TypeInfo, i.e. it is nested? | 144 // BUG: What if this is the wrong TypeInfo, i.e. it is nested? |
145 if (id.toChars()[0] == 'T') | 145 if (id.toChars()[0] == 'T') |
146 { | 146 { |
147 if (id is Id.TypeInfo) | 147 if (id is Id.TypeInfo) |
148 { | 148 { |
149 if (global.typeinfo) { | 149 if (global.typeinfo) { |
150 global.typeinfo.error("%s", msg); | 150 global.typeinfo.error("%s", msg); |
151 } | 151 } |
152 | 152 |
153 global.typeinfo = this; | 153 global.typeinfo = this; |
154 } | 154 } |
155 | 155 |
156 if (id is Id.TypeInfo_Class) | 156 if (id is Id.TypeInfo_Class) |
157 { | 157 { |
158 if (global.typeinfoclass) | 158 if (global.typeinfoclass) |
159 global.typeinfoclass.error("%s", msg); | 159 global.typeinfoclass.error("%s", msg); |
160 global.typeinfoclass = this; | 160 global.typeinfoclass = this; |
161 } | 161 } |
162 | 162 |
163 if (id is Id.TypeInfo_Interface) | 163 if (id is Id.TypeInfo_Interface) |
164 { | 164 { |
165 if (global.typeinfointerface) | 165 if (global.typeinfointerface) |
166 global.typeinfointerface.error("%s", msg); | 166 global.typeinfointerface.error("%s", msg); |
167 global.typeinfointerface = this; | 167 global.typeinfointerface = this; |
168 } | 168 } |
169 | 169 |
170 if (id is Id.TypeInfo_Struct) | 170 if (id is Id.TypeInfo_Struct) |
171 { | 171 { |
172 if (global.typeinfostruct) | 172 if (global.typeinfostruct) |
173 global.typeinfostruct.error("%s", msg); | 173 global.typeinfostruct.error("%s", msg); |
174 global.typeinfostruct = this; | 174 global.typeinfostruct = this; |
175 } | 175 } |
176 | 176 |
177 if (id is Id.TypeInfo_Typedef) | 177 if (id is Id.TypeInfo_Typedef) |
178 { | 178 { |
179 if (global.typeinfotypedef) | 179 if (global.typeinfotypedef) |
180 global.typeinfotypedef.error("%s", msg); | 180 global.typeinfotypedef.error("%s", msg); |
181 global.typeinfotypedef = this; | 181 global.typeinfotypedef = this; |
182 } | 182 } |
183 | 183 |
184 if (id is Id.TypeInfo_Pointer) | 184 if (id is Id.TypeInfo_Pointer) |
185 { | 185 { |
186 if (global.typeinfopointer) | 186 if (global.typeinfopointer) |
187 global.typeinfopointer.error("%s", msg); | 187 global.typeinfopointer.error("%s", msg); |
188 global.typeinfopointer = this; | 188 global.typeinfopointer = this; |
189 } | 189 } |
190 | 190 |
191 if (id is Id.TypeInfo_Array) | 191 if (id is Id.TypeInfo_Array) |
192 { | 192 { |
193 if (global.typeinfoarray) | 193 if (global.typeinfoarray) |
194 global.typeinfoarray.error("%s", msg); | 194 global.typeinfoarray.error("%s", msg); |
195 global.typeinfoarray = this; | 195 global.typeinfoarray = this; |
196 } | 196 } |
197 | 197 |
200 //global.typeinfostaticarray.error("%s", msg); | 200 //global.typeinfostaticarray.error("%s", msg); |
201 global.typeinfostaticarray = this; | 201 global.typeinfostaticarray = this; |
202 } | 202 } |
203 | 203 |
204 if (id is Id.TypeInfo_AssociativeArray) | 204 if (id is Id.TypeInfo_AssociativeArray) |
205 { | 205 { |
206 if (global.typeinfoassociativearray) | 206 if (global.typeinfoassociativearray) |
207 global.typeinfoassociativearray.error("%s", msg); | 207 global.typeinfoassociativearray.error("%s", msg); |
208 global.typeinfoassociativearray = this; | 208 global.typeinfoassociativearray = this; |
209 } | 209 } |
210 | 210 |
211 if (id is Id.TypeInfo_Enum) | 211 if (id is Id.TypeInfo_Enum) |
212 { | 212 { |
213 if (global.typeinfoenum) | 213 if (global.typeinfoenum) |
214 global.typeinfoenum.error("%s", msg); | 214 global.typeinfoenum.error("%s", msg); |
215 global.typeinfoenum = this; | 215 global.typeinfoenum = this; |
216 } | 216 } |
217 | 217 |
218 if (id is Id.TypeInfo_Function) | 218 if (id is Id.TypeInfo_Function) |
219 { | 219 { |
220 if (global.typeinfofunction) | 220 if (global.typeinfofunction) |
221 global.typeinfofunction.error("%s", msg); | 221 global.typeinfofunction.error("%s", msg); |
222 global.typeinfofunction = this; | 222 global.typeinfofunction = this; |
223 } | 223 } |
224 | 224 |
225 if (id is Id.TypeInfo_Delegate) | 225 if (id is Id.TypeInfo_Delegate) |
226 { | 226 { |
227 if (global.typeinfodelegate) | 227 if (global.typeinfodelegate) |
228 global.typeinfodelegate.error("%s", msg); | 228 global.typeinfodelegate.error("%s", msg); |
229 global.typeinfodelegate = this; | 229 global.typeinfodelegate = this; |
230 } | 230 } |
231 | 231 |
232 if (id is Id.TypeInfo_Tuple) | 232 if (id is Id.TypeInfo_Tuple) |
233 { | 233 { |
234 if (global.typeinfotypelist) | 234 if (global.typeinfotypelist) |
235 global.typeinfotypelist.error("%s", msg); | 235 global.typeinfotypelist.error("%s", msg); |
236 global.typeinfotypelist = this; | 236 global.typeinfotypelist = this; |
237 } | 237 } |
238 | 238 |
239 version (DMDV2) { | 239 version (DMDV2) { |
240 if (id is Id.TypeInfo_Const) | 240 if (id is Id.TypeInfo_Const) |
241 { | 241 { |
242 if (global.typeinfoconst) | 242 if (global.typeinfoconst) |
243 global.typeinfoconst.error("%s", msg); | 243 global.typeinfoconst.error("%s", msg); |
244 global.typeinfoconst = this; | 244 global.typeinfoconst = this; |
245 } | 245 } |
246 | 246 |
247 if (id is Id.TypeInfo_Invariant) | 247 if (id is Id.TypeInfo_Invariant) |
248 { | 248 { |
249 if (global.typeinfoinvariant) | 249 if (global.typeinfoinvariant) |
250 global.typeinfoinvariant.error("%s", msg); | 250 global.typeinfoinvariant.error("%s", msg); |
251 global.typeinfoinvariant = this; | 251 global.typeinfoinvariant = this; |
252 } | 252 } |
253 | 253 |
254 if (id is Id.TypeInfo_Shared) | 254 if (id is Id.TypeInfo_Shared) |
255 { | 255 { |
256 if (global.typeinfoshared) | 256 if (global.typeinfoshared) |
257 global.typeinfoshared.error("%s", msg); | 257 global.typeinfoshared.error("%s", msg); |
258 global.typeinfoshared = this; | 258 global.typeinfoshared = this; |
259 } | 259 } |
260 | 260 |
266 } | 266 } |
267 } | 267 } |
268 } | 268 } |
269 | 269 |
270 if (id is Id.Object_) | 270 if (id is Id.Object_) |
271 { | 271 { |
272 if (global.object) | 272 if (global.object) |
273 global.object.error("%s", msg); | 273 global.object.error("%s", msg); |
274 global.object = this; | 274 global.object = this; |
275 } | 275 } |
276 | 276 |
277 // if (id is Id.ClassInfo) | 277 // if (id is Id.ClassInfo) |
278 if (id is Id.TypeInfo_Class) | 278 if (id is Id.TypeInfo_Class) |
279 { | 279 { |
280 if (global.classinfo) | 280 if (global.classinfo) |
281 global.classinfo.error("%s", msg); | 281 global.classinfo.error("%s", msg); |
282 global.classinfo = this; | 282 global.classinfo = this; |
283 } | 283 } |
284 | 284 |
285 if (id is Id.ModuleInfo) | 285 if (id is Id.ModuleInfo) |
286 { | 286 { |
287 if (global.moduleinfo) | 287 if (global.moduleinfo) |
288 global.moduleinfo.error("%s", msg); | 288 global.moduleinfo.error("%s", msg); |
289 global.moduleinfo = this; | 289 global.moduleinfo = this; |
290 } | 290 } |
291 } | 291 } |
293 com = 0; | 293 com = 0; |
294 isauto = false; | 294 isauto = false; |
295 isabstract = false; | 295 isabstract = false; |
296 inuse = 0; | 296 inuse = 0; |
297 } | 297 } |
298 | 298 |
299 override Dsymbol syntaxCopy(Dsymbol s) | 299 override Dsymbol syntaxCopy(Dsymbol s) |
300 { | 300 { |
301 ClassDeclaration cd; | 301 ClassDeclaration cd; |
302 | 302 |
303 //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); | 303 //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); |
317 } | 317 } |
318 | 318 |
319 ScopeDsymbol.syntaxCopy(cd); | 319 ScopeDsymbol.syntaxCopy(cd); |
320 return cd; | 320 return cd; |
321 } | 321 } |
322 | 322 |
323 override void semantic(Scope sc) | 323 override void semantic(Scope sc) |
324 { | 324 { |
325 uint offset; | 325 uint offset; |
326 | 326 |
327 //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); | 327 //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); |
329 //printf("sc.stc = %x\n", sc.stc); | 329 //printf("sc.stc = %x\n", sc.stc); |
330 | 330 |
331 //{ static int n; if (++n == 20) *(char*)0=0; } | 331 //{ static int n; if (++n == 20) *(char*)0=0; } |
332 | 332 |
333 if (!ident) // if anonymous class | 333 if (!ident) // if anonymous class |
334 { | 334 { |
335 string id = "__anonclass"; | 335 string id = "__anonclass"; |
336 ident = Identifier.generateId(id); | 336 ident = Identifier.generateId(id); |
337 } | 337 } |
338 | 338 |
339 if (!sc) | 339 if (!sc) |
344 | 344 |
345 type = type.semantic(loc, sc); | 345 type = type.semantic(loc, sc); |
346 handle = type; | 346 handle = type; |
347 | 347 |
348 if (!members) // if forward reference | 348 if (!members) // if forward reference |
349 { | 349 { |
350 //printf("\tclass '%s' is forward referenced\n", toChars()); | 350 //printf("\tclass '%s' is forward referenced\n", toChars()); |
351 return; | 351 return; |
352 } | 352 } |
353 if (symtab) | 353 if (symtab) |
354 { if (sizeok == 1 || !scope_) | 354 { if (sizeok == 1 || !scope_) |
377 if (sc.linkage == LINK.LINKcpp) | 377 if (sc.linkage == LINK.LINKcpp) |
378 error("cannot create C++ classes"); | 378 error("cannot create C++ classes"); |
379 | 379 |
380 // Expand any tuples in baseclasses[] | 380 // Expand any tuples in baseclasses[] |
381 for (size_t i = 0; i < baseclasses.dim; ) | 381 for (size_t i = 0; i < baseclasses.dim; ) |
382 { | 382 { |
383 auto b = baseclasses[i]; | 383 auto b = baseclasses[i]; |
384 //printf("test1 %s %s\n", toChars(), b.type.toChars()); | 384 //printf("test1 %s %s\n", toChars(), b.type.toChars()); |
385 b.type = b.type.semantic(loc, sc); | 385 b.type = b.type.semantic(loc, sc); |
386 //printf("test2\n"); | 386 //printf("test2\n"); |
387 Type tb = b.type.toBasetype(); | 387 Type tb = b.type.toBasetype(); |
388 | 388 |
389 if (tb.ty == TY.Ttuple) | 389 if (tb.ty == TY.Ttuple) |
390 { | 390 { |
391 TypeTuple tup = cast(TypeTuple)tb; | 391 TypeTuple tup = cast(TypeTuple)tb; |
392 enum PROT protection = b.protection; | 392 enum PROT protection = b.protection; |
393 baseclasses.remove(i); | 393 baseclasses.remove(i); |
394 size_t dim = Parameter.dim(tup.arguments); | 394 size_t dim = Parameter.dim(tup.arguments); |
395 for (size_t j = 0; j < dim; j++) | 395 for (size_t j = 0; j < dim; j++) |
396 { | 396 { |
397 auto arg = Parameter.getNth(tup.arguments, j); | 397 auto arg = Parameter.getNth(tup.arguments, j); |
398 b = new BaseClass(arg.type, protection); | 398 b = new BaseClass(arg.type, protection); |
399 baseclasses.insert(i + j, b); | 399 baseclasses.insert(i + j, b); |
400 } | 400 } |
401 } | 401 } |
403 i++; | 403 i++; |
404 } | 404 } |
405 | 405 |
406 // See if there's a base class as first in baseclasses[] | 406 // See if there's a base class as first in baseclasses[] |
407 if (baseclasses.dim) | 407 if (baseclasses.dim) |
408 { | 408 { |
409 TypeClass tc; | 409 TypeClass tc; |
410 BaseClass b; | 410 BaseClass b; |
411 Type tb; | 411 Type tb; |
412 | 412 |
413 b = baseclasses[0]; | 413 b = baseclasses[0]; |
623 } | 623 } |
624 isnested = false; | 624 isnested = false; |
625 } | 625 } |
626 } | 626 } |
627 else if (!(storage_class & STC.STCstatic)) | 627 else if (!(storage_class & STC.STCstatic)) |
628 { | 628 { |
629 Dsymbol s = toParent2(); | 629 Dsymbol s = toParent2(); |
630 if (s) | 630 if (s) |
631 { | 631 { |
632 AggregateDeclaration ad = s.isClassDeclaration(); | 632 AggregateDeclaration ad = s.isClassDeclaration(); |
633 FuncDeclaration fd = s.isFuncDeclaration(); | 633 FuncDeclaration fd = s.isFuncDeclaration(); |
636 { isnested = true; | 636 { isnested = true; |
637 Type t; | 637 Type t; |
638 if (ad) | 638 if (ad) |
639 t = ad.handle; | 639 t = ad.handle; |
640 else if (fd) | 640 else if (fd) |
641 { | 641 { |
642 AggregateDeclaration ad2 = fd.isMember2(); | 642 AggregateDeclaration ad2 = fd.isMember2(); |
643 if (ad2) | 643 if (ad2) |
644 t = ad2.handle; | 644 t = ad2.handle; |
645 else | 645 else |
646 { | 646 { |
647 t = Type.tvoidptr; | 647 t = global.tvoidptr; |
648 } | 648 } |
649 } | 649 } |
650 else | 650 else |
651 assert(0); | 651 assert(0); |
652 if (t.ty == TY.Tstruct) // ref to struct | 652 if (t.ty == TY.Tstruct) // ref to struct |
653 t = Type.tvoidptr; | 653 t = global.tvoidptr; |
654 assert(!vthis); | 654 assert(!vthis); |
655 vthis = new ThisDeclaration(loc, t); | 655 vthis = new ThisDeclaration(loc, t); |
656 members.push(vthis); | 656 members.push(vthis); |
657 } | 657 } |
658 } | 658 } |
718 { | 718 { |
719 //printf("setScope %s %s\n", s->kind(), s->toChars()); | 719 //printf("setScope %s %s\n", s->kind(), s->toChars()); |
720 s.setScope(sc); | 720 s.setScope(sc); |
721 } | 721 } |
722 } | 722 } |
723 | 723 |
724 foreach (Dsymbol s; members) { | 724 foreach (Dsymbol s; members) { |
725 s.semantic(sc); | 725 s.semantic(sc); |
726 } | 726 } |
727 | 727 |
728 if (sizeok == 2) | 728 if (sizeok == 2) |
830 //b.fillVtbl(this, &b.vtbl, 1); | 830 //b.fillVtbl(this, &b.vtbl, 1); |
831 } | 831 } |
832 } | 832 } |
833 //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); | 833 //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); |
834 } | 834 } |
835 | 835 |
836 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) | 836 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
837 { | 837 { |
838 if (!isAnonymous()) | 838 if (!isAnonymous()) |
839 { | 839 { |
840 buf.printf("%s ", kind()); | 840 buf.printf("%s ", kind()); |
863 } | 863 } |
864 else | 864 else |
865 buf.writeByte(';'); | 865 buf.writeByte(';'); |
866 buf.writenl(); | 866 buf.writenl(); |
867 } | 867 } |
868 | 868 |
869 /********************************************* | 869 /********************************************* |
870 * Determine if 'this' is a base class of cd. | 870 * Determine if 'this' is a base class of cd. |
871 * This is used to detect circular inheritance only. | 871 * This is used to detect circular inheritance only. |
872 */ | 872 */ |
873 int isBaseOf2(ClassDeclaration cd) | 873 int isBaseOf2(ClassDeclaration cd) |
874 { | 874 { |
875 if (!cd) | 875 if (!cd) |
876 return 0; | 876 return 0; |
877 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); | 877 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); |
878 foreach (b; cd.baseclasses) | 878 foreach (b; cd.baseclasses) |
879 { | 879 { |
880 if (b.base is this || isBaseOf2(b.base)) | 880 if (b.base is this || isBaseOf2(b.base)) |
881 return 1; | 881 return 1; |
882 } | 882 } |
883 return 0; | 883 return 0; |
884 } | 884 } |
891 { | 891 { |
892 if (!cd) | 892 if (!cd) |
893 return 0; | 893 return 0; |
894 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); | 894 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); |
895 foreach (b; cd.baseclasses) | 895 foreach (b; cd.baseclasses) |
896 { | 896 { |
897 if (b.base == this || isBaseOf2(b.base)) | 897 if (b.base == this || isBaseOf2(b.base)) |
898 return 1; | 898 return 1; |
899 } | 899 } |
900 | 900 |
901 return 0; | 901 return 0; |
945 } | 945 } |
946 } | 946 } |
947 } | 947 } |
948 return s; | 948 return s; |
949 } | 949 } |
950 | 950 |
951 version (DMDV2) { | 951 version (DMDV2) { |
952 bool isFuncHidden(FuncDeclaration fd) | 952 bool isFuncHidden(FuncDeclaration fd) |
953 { | 953 { |
954 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); | 954 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); |
955 Dsymbol s = search(Loc(0), fd.ident, 4|2); | 955 Dsymbol s = search(Loc(0), fd.ident, 4|2); |
956 if (!s) | 956 if (!s) |
957 { | 957 { |
958 //printf("not found\n"); | 958 //printf("not found\n"); |
959 /* Because, due to a hack, if there are multiple definitions | 959 /* Because, due to a hack, if there are multiple definitions |
960 * of fd.ident, null is returned. | 960 * of fd.ident, null is returned. |
961 */ | 961 */ |
962 return false; | 962 return false; |
963 } | 963 } |
964 | 964 |
965 FuncDeclarationFinder p; p.fd = fd; | 965 FuncDeclarationFinder p; p.fd = fd; |
966 | 966 |
967 s = s.toAlias(); | 967 s = s.toAlias(); |
968 OverloadSet os = s.isOverloadSet(); | 968 OverloadSet os = s.isOverloadSet(); |
969 if (os) | 969 if (os) |
970 { | 970 { |
971 foreach (s2; os.a) | 971 foreach (s2; os.a) |
972 { | 972 { |
973 auto f2 = s2.isFuncDeclaration(); | 973 auto f2 = s2.isFuncDeclaration(); |
974 if (f2 && overloadApply(f2, p)) | 974 if (f2 && overloadApply(f2, p)) |
975 return false; | 975 return false; |
976 } | 976 } |
977 return true; | 977 return true; |
1051 } | 1051 } |
1052 bool isCOMclass() | 1052 bool isCOMclass() |
1053 { | 1053 { |
1054 return com; | 1054 return com; |
1055 } | 1055 } |
1056 | 1056 |
1057 bool isCOMinterface() | 1057 bool isCOMinterface() |
1058 { | 1058 { |
1059 return false; | 1059 return false; |
1060 } | 1060 } |
1061 | 1061 |
1082 } | 1082 } |
1083 } | 1083 } |
1084 | 1084 |
1085 return false; | 1085 return false; |
1086 } | 1086 } |
1087 | 1087 |
1088 int vtblOffset() | 1088 int vtblOffset() |
1089 { | 1089 { |
1090 assert(false); | 1090 assert(false); |
1091 } | 1091 } |
1092 | 1092 |
1093 override string kind() | 1093 override string kind() |
1094 { | 1094 { |
1095 return "class"; | 1095 return "class"; |
1096 } | 1096 } |
1097 | 1097 |
1098 override string mangle() | 1098 override string mangle() |
1099 { | 1099 { |
1100 Dsymbol parentsave = parent; | 1100 Dsymbol parentsave = parent; |
1101 | 1101 |
1102 //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); | 1102 //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); |
1103 | 1103 |
1104 /* These are reserved to the compiler, so keep simple | 1104 /* These are reserved to the compiler, so keep simple |
1105 * names for them. | 1105 * names for them. |
1106 */ | 1106 */ |
1107 if (ident is Id.Exception) | 1107 if (ident is Id.Exception) |
1108 { | 1108 { |
1109 if (parent.ident is Id.object) | 1109 if (parent.ident is Id.object) |
1110 parent = null; | 1110 parent = null; |
1111 } | 1111 } |
1112 else if (ident is Id.TypeInfo || | 1112 else if (ident is Id.TypeInfo || |
1113 // ident is Id.Exception || | 1113 // ident is Id.Exception || |
1126 | 1126 |
1127 string id = Dsymbol.mangle(); | 1127 string id = Dsymbol.mangle(); |
1128 parent = parentsave; | 1128 parent = parentsave; |
1129 return id; | 1129 return id; |
1130 } | 1130 } |
1131 | 1131 |
1132 override void toDocBuffer(OutBuffer buf) | 1132 override void toDocBuffer(OutBuffer buf) |
1133 { | 1133 { |
1134 assert(false); | 1134 assert(false); |
1135 } | 1135 } |
1136 | 1136 |
1154 { | 1154 { |
1155 access_ret = smember.prot(); | 1155 access_ret = smember.prot(); |
1156 } | 1156 } |
1157 | 1157 |
1158 foreach (b; baseclasses) | 1158 foreach (b; baseclasses) |
1159 { | 1159 { |
1160 access = b.base.getAccess(smember); | 1160 access = b.base.getAccess(smember); |
1161 switch (access) | 1161 switch (access) |
1162 { | 1162 { |
1163 case PROT.PROTnone: | 1163 case PROT.PROTnone: |
1164 break; | 1164 break; |
1210 | 1210 |
1211 if (!members) | 1211 if (!members) |
1212 return; | 1212 return; |
1213 | 1213 |
1214 if (multiobj) | 1214 if (multiobj) |
1215 { | 1215 { |
1216 obj_append(this); | 1216 obj_append(this); |
1217 return; | 1217 return; |
1218 } | 1218 } |
1219 | 1219 |
1220 if (global.params.symdebug) | 1220 if (global.params.symdebug) |
1232 | 1232 |
1233 static if (false) { | 1233 static if (false) { |
1234 // Build destructor by aggregating dtors[] | 1234 // Build destructor by aggregating dtors[] |
1235 Symbol* sdtor; | 1235 Symbol* sdtor; |
1236 switch (dtors.dim) | 1236 switch (dtors.dim) |
1237 { | 1237 { |
1238 case 0: | 1238 case 0: |
1239 // No destructors for this class | 1239 // No destructors for this class |
1240 sdtor = null; | 1240 sdtor = null; |
1241 break; | 1241 break; |
1242 | 1242 |
1244 // One destructor, just use it directly | 1244 // One destructor, just use it directly |
1245 sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); | 1245 sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); |
1246 break; | 1246 break; |
1247 | 1247 |
1248 default: | 1248 default: |
1249 { | 1249 { |
1250 /* Build a destructor that calls all the | 1250 /* Build a destructor that calls all the |
1251 * other destructors in dtors[]. | 1251 * other destructors in dtors[]. |
1252 */ | 1252 */ |
1253 | 1253 |
1254 elem* edtor = null; | 1254 elem* edtor = null; |
1262 sthis.Sfl = FLauto; | 1262 sthis.Sfl = FLauto; |
1263 | 1263 |
1264 // Call each of the destructors in dtors[] | 1264 // Call each of the destructors in dtors[] |
1265 // in reverse order | 1265 // in reverse order |
1266 for (size_t i = 0; i < dtors.dim; i++) | 1266 for (size_t i = 0; i < dtors.dim; i++) |
1267 { | 1267 { |
1268 DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; | 1268 DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; |
1269 Symbol* s = d.toSymbol(); | 1269 Symbol* s = d.toSymbol(); |
1270 elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); | 1270 elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); |
1271 edtor = el_combine(e, edtor); | 1271 edtor = el_combine(e, edtor); |
1272 } | 1272 } |
1346 offset = CLASSINFO_SIZE; // must be ClassInfo.size | 1346 offset = CLASSINFO_SIZE; // must be ClassInfo.size |
1347 if (global.classinfo) | 1347 if (global.classinfo) |
1348 { | 1348 { |
1349 if (global.classinfo.structsize != CLASSINFO_SIZE) | 1349 if (global.classinfo.structsize != CLASSINFO_SIZE) |
1350 error("D compiler and phobos' object.d are mismatched"); | 1350 error("D compiler and phobos' object.d are mismatched"); |
1351 | 1351 |
1352 dtxoff(&dt, global.classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo | 1352 dtxoff(&dt, global.classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo |
1353 } | 1353 } |
1354 else | 1354 else |
1355 { | 1355 { |
1356 dtdword(&dt, 0); // BUG: should be an assert() | 1356 dtdword(&dt, 0); // BUG: should be an assert() |
1365 | 1365 |
1366 // name[] | 1366 // name[] |
1367 string name = ident.toChars(); | 1367 string name = ident.toChars(); |
1368 size_t namelen = name.length; | 1368 size_t namelen = name.length; |
1369 if (!(namelen > 9 && name[0..9] == "TypeInfo_")) | 1369 if (!(namelen > 9 && name[0..9] == "TypeInfo_")) |
1370 { | 1370 { |
1371 name = toPrettyChars(); | 1371 name = toPrettyChars(); |
1372 namelen = name.length; | 1372 namelen = name.length; |
1373 } | 1373 } |
1374 dtdword(&dt, namelen); | 1374 dtdword(&dt, namelen); |
1375 dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); | 1375 dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); |
1461 // Put out vtblInterfaces.data[]. Must immediately follow csym, because | 1461 // Put out vtblInterfaces.data[]. Must immediately follow csym, because |
1462 // of the fixup (*) | 1462 // of the fixup (*) |
1463 | 1463 |
1464 offset += vtblInterfaces.dim * (4 * PTRSIZE); | 1464 offset += vtblInterfaces.dim * (4 * PTRSIZE); |
1465 foreach (b; vtblInterfaces) | 1465 foreach (b; vtblInterfaces) |
1466 { | 1466 { |
1467 ClassDeclaration id = b.base; | 1467 ClassDeclaration id = b.base; |
1468 | 1468 |
1469 /* The layout is: | 1469 /* The layout is: |
1470 * struct Interface | 1470 * struct Interface |
1471 * { | 1471 * { |
1491 | 1491 |
1492 // Put out the vtblInterfaces.data[].vtbl[] | 1492 // Put out the vtblInterfaces.data[].vtbl[] |
1493 // This must be mirrored with ClassDeclaration.baseVtblOffset() | 1493 // This must be mirrored with ClassDeclaration.baseVtblOffset() |
1494 //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); | 1494 //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); |
1495 foreach (size_t i, BaseClass b; vtblInterfaces) | 1495 foreach (size_t i, BaseClass b; vtblInterfaces) |
1496 { | 1496 { |
1497 ClassDeclaration id = b.base; | 1497 ClassDeclaration id = b.base; |
1498 int j; | 1498 int j; |
1499 | 1499 |
1500 //printf(" interface[%d] is '%s'\n", i, id.toChars()); | 1500 //printf(" interface[%d] is '%s'\n", i, id.toChars()); |
1501 j = 0; | 1501 j = 0; |
1506 | 1506 |
1507 // First entry is struct Interface reference | 1507 // First entry is struct Interface reference |
1508 dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); | 1508 dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); |
1509 j = 1; | 1509 j = 1; |
1510 } | 1510 } |
1511 | 1511 |
1512 assert(id.vtbl.dim == b.vtbl.dim); | 1512 assert(id.vtbl.dim == b.vtbl.dim); |
1513 for (; j < id.vtbl.dim; j++) | 1513 for (; j < id.vtbl.dim; j++) |
1514 { | 1514 { |
1515 assert(j < b.vtbl.dim); | 1515 assert(j < b.vtbl.dim); |
1516 static if (false) { | 1516 static if (false) { |
1539 scope Array bvtbl = new Array(); | 1539 scope Array bvtbl = new Array(); |
1540 | 1540 |
1541 for (cd = this.baseClass; cd; cd = cd.baseClass) | 1541 for (cd = this.baseClass; cd; cd = cd.baseClass) |
1542 { | 1542 { |
1543 foreach (size_t k, BaseClass bs; cd.vtblInterfaces) | 1543 foreach (size_t k, BaseClass bs; cd.vtblInterfaces) |
1544 { | 1544 { |
1545 if (bs.fillVtbl(this, bvtbl, 0)) | 1545 if (bs.fillVtbl(this, bvtbl, 0)) |
1546 { | 1546 { |
1547 //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); | 1547 //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); |
1548 ClassDeclaration id = bs.base; | 1548 ClassDeclaration id = bs.base; |
1549 int j; | 1549 int j; |
1570 } | 1570 } |
1571 } | 1571 } |
1572 } | 1572 } |
1573 } | 1573 } |
1574 } | 1574 } |
1575 | 1575 |
1576 version (INTERFACE_VIRTUAL) { | 1576 version (INTERFACE_VIRTUAL) { |
1577 // Put out the overriding interface vtbl[]s. | 1577 // Put out the overriding interface vtbl[]s. |
1578 // This must be mirrored with ClassDeclaration.baseVtblOffset() | 1578 // This must be mirrored with ClassDeclaration.baseVtblOffset() |
1579 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); | 1579 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); |
1580 for (size_t i = 0; i < vtblInterfaces.dim; i++) | 1580 for (size_t i = 0; i < vtblInterfaces.dim; i++) |
1581 { | 1581 { |
1582 BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; | 1582 BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; |
1583 ClassDeclaration cd; | 1583 ClassDeclaration cd; |
1584 | 1584 |
1585 for (cd = this.baseClass; cd; cd = cd.baseClass) | 1585 for (cd = this.baseClass; cd; cd = cd.baseClass) |
1586 { | 1586 { |
1587 for (int k = 0; k < cd.vtblInterfaces.dim; k++) | 1587 for (int k = 0; k < cd.vtblInterfaces.dim; k++) |
1588 { | 1588 { |
1589 BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; | 1589 BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; |
1590 | 1590 |
1591 if (b.base == bs.base) | 1591 if (b.base == bs.base) |
1592 { | 1592 { |
1593 //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); | 1593 //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); |
1637 dt = null; | 1637 dt = null; |
1638 size_t i; | 1638 size_t i; |
1639 if (0) | 1639 if (0) |
1640 i = 0; | 1640 i = 0; |
1641 else | 1641 else |
1642 { | 1642 { |
1643 dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference | 1643 dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference |
1644 i = 1; | 1644 i = 1; |
1645 } | 1645 } |
1646 for (; i < vtbl.dim; i++) | 1646 for (; i < vtbl.dim; i++) |
1647 { | 1647 { |
1648 FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); | 1648 FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); |
1649 | 1649 |
1650 //printf("\tvtbl[%d] = %p\n", i, fd); | 1650 //printf("\tvtbl[%d] = %p\n", i, fd); |
1651 if (fd && (fd.fbody || !isAbstract())) | 1651 if (fd && (fd.fbody || !isAbstract())) |
1652 { | 1652 { |
1653 Symbol* s = fd.toSymbol(); | 1653 Symbol* s = fd.toSymbol(); |
1654 | 1654 |
1655 version (DMDV2) { | 1655 version (DMDV2) { |
1656 if (isFuncHidden(fd)) | 1656 if (isFuncHidden(fd)) |
1657 { | 1657 { |
1658 /* fd is hidden from the view of this class. | 1658 /* fd is hidden from the view of this class. |
1659 * If fd overlaps with any function in the vtbl[], then | 1659 * If fd overlaps with any function in the vtbl[], then |
1660 * issue 'hidden' error. | 1660 * issue 'hidden' error. |
1661 */ | 1661 */ |
1662 for (int j = 1; j < vtbl.dim; j++) | 1662 for (int j = 1; j < vtbl.dim; j++) |
1663 { | 1663 { |
1664 if (j == i) | 1664 if (j == i) |
1665 continue; | 1665 continue; |
1666 FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); | 1666 FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); |
1667 if (!fd2.ident.equals(fd.ident)) | 1667 if (!fd2.ident.equals(fd.ident)) |
1668 continue; | 1668 continue; |
1699 } | 1699 } |
1700 outdata(vtblsym); | 1700 outdata(vtblsym); |
1701 if (isExport()) | 1701 if (isExport()) |
1702 obj_export(vtblsym,0); | 1702 obj_export(vtblsym,0); |
1703 } | 1703 } |
1704 | 1704 |
1705 void toDebug() | 1705 void toDebug() |
1706 { | 1706 { |
1707 assert(false); | 1707 assert(false); |
1708 } | 1708 } |
1709 | 1709 |
1710 /****************************************** | 1710 /****************************************** |
1711 * Get offset of base class's vtbl[] initializer from start of csym. | 1711 * Get offset of base class's vtbl[] initializer from start of csym. |
1712 * Returns ~0 if not this csym. | 1712 * Returns ~0 if not this csym. |
1713 */ | 1713 */ |
1714 uint baseVtblOffset(BaseClass bc) | 1714 uint baseVtblOffset(BaseClass bc) |
1734 Array bvtbl; | 1734 Array bvtbl; |
1735 | 1735 |
1736 for (cd = this.baseClass; cd; cd = cd.baseClass) | 1736 for (cd = this.baseClass; cd; cd = cd.baseClass) |
1737 { | 1737 { |
1738 foreach(bs; cd.vtblInterfaces) | 1738 foreach(bs; cd.vtblInterfaces) |
1739 { | 1739 { |
1740 if (bs.fillVtbl(this, null, 0)) | 1740 if (bs.fillVtbl(this, null, 0)) |
1741 { | 1741 { |
1742 if (bc == bs) | 1742 if (bc == bs) |
1743 { | 1743 { |
1744 //printf("\tcsymoffset = x%x\n", csymoffset); | 1744 //printf("\tcsymoffset = x%x\n", csymoffset); |
1745 return csymoffset; | 1745 return csymoffset; |
1746 } | 1746 } |
1747 csymoffset += bs.base.vtbl.dim * PTRSIZE; | 1747 csymoffset += bs.base.vtbl.dim * PTRSIZE; |
1748 } | 1748 } |
1749 } | 1749 } |
1750 } | 1750 } |
1751 } | 1751 } |
1752 version (INTERFACE_VIRTUAL) { | 1752 version (INTERFACE_VIRTUAL) { |
1753 for (size_t i = 0; i < vtblInterfaces.dim; i++) | 1753 for (size_t i = 0; i < vtblInterfaces.dim; i++) |
1754 { | 1754 { |
1755 BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; | 1755 BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; |
1756 ClassDeclaration cd; | 1756 ClassDeclaration cd; |
1757 | 1757 |
1758 for (cd = this.baseClass; cd; cd = cd.baseClass) | 1758 for (cd = this.baseClass; cd; cd = cd.baseClass) |
1759 { | 1759 { |
1760 //printf("\tbase class %s\n", cd.toChars()); | 1760 //printf("\tbase class %s\n", cd.toChars()); |
1761 for (int k = 0; k < cd.vtblInterfaces.dim; k++) | 1761 for (int k = 0; k < cd.vtblInterfaces.dim; k++) |
1762 { | 1762 { |
1763 BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; | 1763 BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; |
1764 | 1764 |
1765 if (bc == bs) | 1765 if (bc == bs) |
1766 { | 1766 { |
1767 //printf("\tcsymoffset = x%x\n", csymoffset); | 1767 //printf("\tcsymoffset = x%x\n", csymoffset); |
1768 return csymoffset; | 1768 return csymoffset; |
1769 } | 1769 } |
1770 if (b.base == bs.base) | 1770 if (b.base == bs.base) |
1771 csymoffset += bs.base.vtbl.dim * PTRSIZE; | 1771 csymoffset += bs.base.vtbl.dim * PTRSIZE; |
1774 } | 1774 } |
1775 } | 1775 } |
1776 | 1776 |
1777 return ~0; | 1777 return ~0; |
1778 } | 1778 } |
1779 | |
1780 static private __gshared Classsym* scc; | |
1781 | 1779 |
1782 /************************************* | 1780 /************************************* |
1783 * Create the "ClassInfo" symbol | 1781 * Create the "ClassInfo" symbol |
1784 */ | 1782 */ |
1785 override Symbol* toSymbol() | 1783 override Symbol* toSymbol() |
1786 { | 1784 { |
1787 if (!csym) | 1785 if (!csym) |
1788 { | 1786 { |
1789 Symbol* s; | 1787 Symbol* s; |
1790 | 1788 |
1791 if (!scc) | 1789 s = toSymbolX("__Class", SC.SCextern, global.scc.Stype, "Z"); |
1792 scc = fake_classsym(Id.ClassInfo); | |
1793 | |
1794 s = toSymbolX("__Class", SC.SCextern, scc.Stype, "Z"); | |
1795 s.Sfl = FL.FLextern; | 1790 s.Sfl = FL.FLextern; |
1796 s.Sflags |= SFL.SFLnodebug; | 1791 s.Sflags |= SFL.SFLnodebug; |
1797 csym = s; | 1792 csym = s; |
1798 slist_add(s); | 1793 slist_add(s); |
1799 } | 1794 } |
1823 vtblsym = s; | 1818 vtblsym = s; |
1824 slist_add(s); | 1819 slist_add(s); |
1825 } | 1820 } |
1826 return vtblsym; | 1821 return vtblsym; |
1827 } | 1822 } |
1828 | 1823 |
1829 // Generate the data for the static initializer. | 1824 // Generate the data for the static initializer. |
1830 void toDt(dt_t **pdt) | 1825 void toDt(dt_t **pdt) |
1831 { | 1826 { |
1832 //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); | 1827 //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); |
1833 | 1828 |
1838 // Put in the rest | 1833 // Put in the rest |
1839 toDt2(pdt, this); | 1834 toDt2(pdt, this); |
1840 | 1835 |
1841 //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); | 1836 //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); |
1842 } | 1837 } |
1843 | 1838 |
1844 void toDt2(dt_t** pdt, ClassDeclaration cd) | 1839 void toDt2(dt_t** pdt, ClassDeclaration cd) |
1845 { | 1840 { |
1846 uint offset; | 1841 uint offset; |
1847 | 1842 |
1848 dt_t* dt; | 1843 dt_t* dt; |
1869 | 1864 |
1870 //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); | 1865 //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); |
1871 dt = null; | 1866 dt = null; |
1872 init = v.init; | 1867 init = v.init; |
1873 if (init) | 1868 if (init) |
1874 { | 1869 { |
1875 //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); | 1870 //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); |
1876 ExpInitializer ei = init.isExpInitializer(); | 1871 ExpInitializer ei = init.isExpInitializer(); |
1877 Type tb = v.type.toBasetype(); | 1872 Type tb = v.type.toBasetype(); |
1878 if (ei && tb.ty == Tsarray) | 1873 if (ei && tb.ty == Tsarray) |
1879 (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); | 1874 (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); |
1900 | 1895 |
1901 // Interface vptr initializations | 1896 // Interface vptr initializations |
1902 toSymbol(); // define csym | 1897 toSymbol(); // define csym |
1903 | 1898 |
1904 foreach (b; vtblInterfaces) | 1899 foreach (b; vtblInterfaces) |
1905 { | 1900 { |
1906 /// version (1 || INTERFACE_VIRTUAL) { | 1901 /// version (1 || INTERFACE_VIRTUAL) { |
1907 for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) | 1902 for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) |
1908 { | 1903 { |
1909 assert(cd2); | 1904 assert(cd2); |
1910 csymoffset = cd2.baseVtblOffset(b); | 1905 csymoffset = cd2.baseVtblOffset(b); |