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);