root/branches/dmdfe-2.0/class.c

Revision 914, 33.6 kB (checked in by Gregor, 3 months ago)

MERGE: DMD 2.019

Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2008 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13
14 #include "root.h"
15 #include "mem.h"
16
17 #include "enum.h"
18 #include "init.h"
19 #include "attrib.h"
20 #include "declaration.h"
21 #include "aggregate.h"
22 #include "id.h"
23 #include "mtype.h"
24 #include "scope.h"
25 #include "module.h"
26 #include "expression.h"
27 #include "statement.h"
28
29 /********************************* ClassDeclaration ****************************/
30
31 ClassDeclaration *ClassDeclaration::classinfo;
32 ClassDeclaration *ClassDeclaration::object;
33
34 ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
35     : AggregateDeclaration(loc, id)
36 {
37     static char msg[] = "only object.d can define this reserved class name";
38
39     if (baseclasses)
40     this->baseclasses = *baseclasses;
41     baseClass = NULL;
42
43     interfaces_dim = 0;
44     interfaces = NULL;
45
46     vtblInterfaces = NULL;
47
48     //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses.dim);
49
50     // For forward references
51     type = new TypeClass(this);
52     handle = type;
53
54     staticCtor = NULL;
55     staticDtor = NULL;
56
57     vtblsym = NULL;
58     vclassinfo = NULL;
59
60     if (id)
61     {   // Look for special class names
62
63     if (id == Id::__sizeof || id == Id::alignof || id == Id::mangleof)
64         error("illegal class name");
65
66     // BUG: What if this is the wrong TypeInfo, i.e. it is nested?
67     if (id->toChars()[0] == 'T')
68     {
69         if (id == Id::TypeInfo)
70         {   if (Type::typeinfo)
71             Type::typeinfo->error("%s", msg);
72         Type::typeinfo = this;
73         }
74
75         if (id == Id::TypeInfo_Class)
76         {   if (Type::typeinfoclass)
77             Type::typeinfoclass->error("%s", msg);
78         Type::typeinfoclass = this;
79         }
80
81         if (id == Id::TypeInfo_Interface)
82         {   if (Type::typeinfointerface)
83             Type::typeinfointerface->error("%s", msg);
84         Type::typeinfointerface = this;
85         }
86
87         if (id == Id::TypeInfo_Struct)
88         {   if (Type::typeinfostruct)
89             Type::typeinfostruct->error("%s", msg);
90         Type::typeinfostruct = this;
91         }
92
93         if (id == Id::TypeInfo_Typedef)
94         {   if (Type::typeinfotypedef)
95             Type::typeinfotypedef->error("%s", msg);
96         Type::typeinfotypedef = this;
97         }
98
99         if (id == Id::TypeInfo_Pointer)
100         {   if (Type::typeinfopointer)
101             Type::typeinfopointer->error("%s", msg);
102         Type::typeinfopointer = this;
103         }
104
105         if (id == Id::TypeInfo_Array)
106         {   if (Type::typeinfoarray)
107             Type::typeinfoarray->error("%s", msg);
108         Type::typeinfoarray = this;
109         }
110
111         if (id == Id::TypeInfo_StaticArray)
112         {   //if (Type::typeinfostaticarray)
113             //Type::typeinfostaticarray->error("%s", msg);
114         Type::typeinfostaticarray = this;
115         }
116
117         if (id == Id::TypeInfo_AssociativeArray)
118         {   if (Type::typeinfoassociativearray)
119             Type::typeinfoassociativearray->error("%s", msg);
120         Type::typeinfoassociativearray = this;
121         }
122
123         if (id == Id::TypeInfo_Enum)
124         {   if (Type::typeinfoenum)
125             Type::typeinfoenum->error("%s", msg);
126         Type::typeinfoenum = this;
127         }
128
129         if (id == Id::TypeInfo_Function)
130         {   if (Type::typeinfofunction)
131             Type::typeinfofunction->error("%s", msg);
132         Type::typeinfofunction = this;
133         }
134
135         if (id == Id::TypeInfo_Delegate)
136         {   if (Type::typeinfodelegate)
137             Type::typeinfodelegate->error("%s", msg);
138         Type::typeinfodelegate = this;
139         }
140
141         if (id == Id::TypeInfo_Tuple)
142         {   if (Type::typeinfotypelist)
143             Type::typeinfotypelist->error("%s", msg);
144         Type::typeinfotypelist = this;
145         }
146
147 #if V2
148         if (id == Id::TypeInfo_Const)
149         {   if (Type::typeinfoconst)
150             Type::typeinfoconst->error("%s", msg);
151         Type::typeinfoconst = this;
152         }
153
154         if (id == Id::TypeInfo_Invariant)
155         {   if (Type::typeinfoinvariant)
156             Type::typeinfoinvariant->error("%s", msg);
157         Type::typeinfoinvariant = this;
158         }
159 #endif
160     }
161
162     if (id == Id::Object)
163     {   if (object)
164         object->error("%s", msg);
165         object = this;
166     }
167
168     if (id == Id::ClassInfo)
169     {   if (classinfo)
170         classinfo->error("%s", msg);
171         classinfo = this;
172     }
173
174     if (id == Id::ModuleInfo)
175     {   if (Module::moduleinfo)
176         Module::moduleinfo->error("%s", msg);
177         Module::moduleinfo = this;
178     }
179     }
180
181     com = 0;
182     isauto = 0;
183     isabstract = 0;
184     isnested = 0;
185     vthis = NULL;
186     inuse = 0;
187 }
188
189 Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
190 {
191     ClassDeclaration *cd;
192
193     //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars());
194     if (s)
195     cd = (ClassDeclaration *)s;
196     else
197     cd = new ClassDeclaration(loc, ident, NULL);
198
199     cd->storage_class |= storage_class;
200
201     cd->baseclasses.setDim(this->baseclasses.dim);
202     for (int i = 0; i < cd->baseclasses.dim; i++)
203     {
204     BaseClass *b = (BaseClass *)this->baseclasses.data[i];
205     BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection);
206     cd->baseclasses.data[i] = b2;
207     }
208
209     ScopeDsymbol::syntaxCopy(cd);
210     return cd;
211 }
212
213 void ClassDeclaration::semantic(Scope *sc)
214 {   int i;
215     unsigned offset;
216
217     //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
218     //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : "");
219     //printf("sc->stc = %x\n", sc->stc);
220
221     //{ static int n;  if (++n == 20) *(char*)0=0; }
222
223     if (!ident)     // if anonymous class
224     {   const char *id = "__anonclass";
225
226     ident = Identifier::generateId(id);
227     }
228
229     if (!scope)
230     {
231     if (!parent && sc->parent && !sc->parent->isModule())
232         parent = sc->parent;
233
234     type = type->semantic(loc, sc);
235     handle = handle->semantic(loc, sc);
236     }
237     if (!members)           // if forward reference
238     {   //printf("\tclass '%s' is forward referenced\n", toChars());
239     return;
240     }
241     if (symtab)
242     {   if (!scope)
243     {   //printf("\tsemantic for '%s' is already completed\n", toChars());
244         return;     // semantic() already completed
245     }
246     }
247     else
248     symtab = new DsymbolTable();
249
250     Scope *scx = NULL;
251     if (scope)
252     {   sc = scope;
253     scx = scope;        // save so we don't make redundant copies
254     scope = NULL;
255     }
256 #ifdef IN_GCC
257     methods.setDim(0);
258 #endif
259
260     if (sc->stc & STCdeprecated)
261     {
262     isdeprecated = 1;
263     }
264
265     if (sc->linkage == LINKcpp)
266     error("cannot create C++ classes");
267
268     // Expand any tuples in baseclasses[]
269     for (i = 0; i < baseclasses.dim; )
270     {   BaseClass *b = (BaseClass *)baseclasses.data[i];
271     b->type = b->type->semantic(loc, sc);
272     Type *tb = b->type->toBasetype();
273
274     if (tb->ty == Ttuple)
275     {   TypeTuple *tup = (TypeTuple *)tb;
276         enum PROT protection = b->protection;
277         baseclasses.remove(i);
278         size_t dim = Argument::dim(tup->arguments);
279         for (size_t j = 0; j < dim; j++)
280         {   Argument *arg = Argument::getNth(tup->arguments, j);
281         b = new BaseClass(arg->type, protection);
282         baseclasses.insert(i + j, b);
283         }
284     }
285     else
286         i++;
287     }
288
289     // See if there's a base class as first in baseclasses[]
290     if (baseclasses.dim)
291     {   TypeClass *tc;
292     BaseClass *b;
293     Type *tb;
294
295     b = (BaseClass *)baseclasses.data[0];
296     //b->type = b->type->semantic(loc, sc);
297     tb = b->type->toBasetype();
298     if (tb->ty != Tclass)
299     {   error("base type must be class or interface, not %s", b->type->toChars());
300         baseclasses.remove(0);
301     }
302     else
303     {
304         tc = (TypeClass *)(tb);
305
306         if (tc->sym->isDeprecated())
307         {
308         if (!isDeprecated())
309         {
310             // Deriving from deprecated class makes this one deprecated too
311             isdeprecated = 1;
312
313             tc->checkDeprecated(loc, sc);
314         }
315         }
316
317         if (tc->sym->isInterfaceDeclaration())
318         ;
319         else
320         {
321         for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass)
322         {
323             if (cdb == this)
324             {
325             error("circular inheritance");
326             baseclasses.remove(0);
327             goto L7;
328             }
329         }
330         if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
331         {
332             //error("forward reference of base class %s", baseClass->toChars());
333             // Forward reference of base class, try again later
334             //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars());
335             scope = scx ? scx : new Scope(*sc);
336             scope->setNoFree();
337             scope->module->addDeferredSemantic(this);
338             return;
339         }
340         else
341         {   baseClass = tc->sym;
342             b->base = baseClass;
343         }
344          L7: ;
345         }
346     }
347     }
348
349     // Treat the remaining entries in baseclasses as interfaces
350     // Check for errors, handle forward references
351     for (i = (baseClass ? 1 : 0); i < baseclasses.dim; )
352     {   TypeClass *tc;
353     BaseClass *b;
354     Type *tb;
355
356     b = (BaseClass *)baseclasses.data[i];
357     b->type = b->type->semantic(loc, sc);
358     tb = b->type->toBasetype();
359     if (tb->ty == Tclass)
360         tc = (TypeClass *)tb;
361     else
362         tc = NULL;
363     if (!tc || !tc->sym->isInterfaceDeclaration())
364     {
365         error("base type must be interface, not %s", b->type->toChars());
366         baseclasses.remove(i);
367         continue;
368     }
369     else
370     {
371         if (tc->sym->isDeprecated())
372         {
373         if (!isDeprecated())
374         {
375             // Deriving from deprecated class makes this one deprecated too
376             isdeprecated = 1;
377
378             tc->checkDeprecated(loc, sc);
379         }
380         }
381
382         // Check for duplicate interfaces
383         for (size_t j = (baseClass ? 1 : 0); j < i; j++)
384         {
385         BaseClass *b2 = (BaseClass *)baseclasses.data[j];
386         if (b2->base == tc->sym)
387             error("inherits from duplicate interface %s", b2->base->toChars());
388         }
389
390         b->base = tc->sym;
391         if (!b->base->symtab || b->base->scope)
392         {
393         //error("forward reference of base class %s", baseClass->toChars());
394         // Forward reference of base, try again later
395         //printf("\ttry later, forward reference of base %s\n", baseClass->toChars());
396         scope = scx ? scx : new Scope(*sc);
397         scope->setNoFree();
398         scope->module->addDeferredSemantic(this);
399         return;
400         }
401     }
402     i++;
403     }
404
405
406     // If no base class, and this is not an Object, use Object as base class
407     if (!baseClass && ident != Id::Object)
408     {
409     // BUG: what if Object is redefined in an inner scope?
410     Type *tbase = new TypeIdentifier(0, Id::Object);
411     BaseClass *b;
412     TypeClass *tc;
413     Type *bt;
414
415     if (!object)
416     {
417         error("missing or corrupt object.d");
418         fatal();
419     }
420     bt = tbase->semantic(loc, sc)->toBasetype();
421     b = new BaseClass(bt, PROTpublic);
422     baseclasses.shift(b);
423     assert(b->type->ty == Tclass);
424     tc = (TypeClass *)(b->type);
425     baseClass = tc->sym;
426     assert(!baseClass->isInterfaceDeclaration());
427     b->base = baseClass;
428     }
429
430     interfaces_dim = baseclasses.dim;
431     interfaces = (BaseClass **)baseclasses.data;
432
433
434     if (baseClass)
435     {
436     if (baseClass->storage_class & STCfinal)
437         error("cannot inherit from final class %s", baseClass->toChars());
438
439     interfaces_dim--;
440     interfaces++;
441
442     // Copy vtbl[] from base class
443     vtbl.setDim(baseClass->vtbl.dim);
444     memcpy(vtbl.data, baseClass->vtbl.data, sizeof(void *) * vtbl.dim);
445
446     // Inherit properties from base class
447     com = baseClass->isCOMclass();
448     isauto = baseClass->isauto;
449     vthis = baseClass->vthis;
450     storage_class |= baseClass->storage_class & (STCconst | STCinvariant);
451     }
452     else
453     {
454     // No base class, so this is the root of the class hierarchy
455     vtbl.setDim(0);
456     vtbl.push(this);        // leave room for classinfo as first member
457     }
458
459     protection = sc->protection;
460     storage_class |= sc->stc;
461
462     if (sizeok == 0)
463     {
464     interfaceSemantic(sc);
465
466     for (i = 0; i < members->dim; i++)
467     {
468         Dsymbol *s = (Dsymbol *)members->data[i];
469         s->addMember(sc, this, 1);
470     }
471
472     /* If this is a nested class, add the hidden 'this'
473      * member which is a pointer to the enclosing scope.
474      */
475     if (vthis)      // if inheriting from nested class
476     {   // Use the base class's 'this' member
477         isnested = 1;
478         if (storage_class & STCstatic)
479         error("static class cannot inherit from nested class %s", baseClass->toChars());
480         if (toParent2() != baseClass->toParent2())
481         {
482         if (toParent2())
483         {
484             error("is nested within %s, but super class %s is nested within %s",
485             toParent2()->toChars(),
486             baseClass->toChars(),
487             baseClass->toParent2()->toChars());
488         }
489         else
490         {
491             error("is not nested, but super class %s is nested within %s",
492             baseClass->toChars(),
493             baseClass->toParent2()->toChars());
494         }
495         isnested = 0;
496         }
497     }
498     else if (!(storage_class & STCstatic))
499     {   Dsymbol *s = toParent2();
500         if (s)
501         {
502         ClassDeclaration *cd = s->isClassDeclaration();
503         FuncDeclaration *fd = s->isFuncDeclaration();
504
505
506         if (cd || fd)
507         {   isnested = 1;
508             Type *t;
509             if (cd)
510             t = cd->type;
511             else if (fd)
512             {   AggregateDeclaration *ad = fd->isMember2();
513             if (ad)
514                 t = ad->handle;
515             else
516             {
517                 t = new TypePointer(Type::tvoid);
518                 t = t->semantic(0, sc);
519             }
520             }
521             else
522             assert(0);
523             assert(!vthis);
524             vthis = new ThisDeclaration(t);
525             members->push(vthis);
526         }
527         }
528     }
529     }
530
531     if (storage_class & (STCauto | STCscope))
532     isauto = 1;
533     if (storage_class & STCabstract)
534     isabstract = 1;
535     if (storage_class & STCinvariant)
536     type = type->invariantOf();
537     else if (storage_class & STCconst)
538     type = type->constOf();
539
540     sc = sc->push(this);
541     sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic |
542          STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls);
543     sc->stc |= storage_class & (STCconst | STCinvariant);
544     sc->parent = this;
545     sc->inunion = 0;
546
547     if (isCOMclass())
548     sc->linkage = LINKwindows;
549     sc->protection = PROTpublic;
550     sc->explicitProtection = 0;
551     sc->structalign = 8;
552     structalign = sc->structalign;
553     if (baseClass)
554     {   sc->offset = baseClass->structsize;
555     alignsize = baseClass->alignsize;
556 //  if (isnested)
557 //      sc->offset += PTRSIZE;  // room for uplevel context pointer
558     }
559     else
560     {   sc->offset = PTRSIZE * 2;   // allow room for __vptr and __monitor
561     alignsize = 4;
562     }
563     structsize = sc->offset;
564     Scope scsave = *sc;
565     int members_dim = members->dim;
566     sizeok = 0;
567     for (i = 0; i < members_dim; i++)
568     {
569     Dsymbol *s = (Dsymbol *)members->data[i];
570     s->semantic(sc);
571     }
572
573     if (sizeok == 2)
574     {   // semantic() failed because of forward references.
575     // Unwind what we did, and defer it for later
576     fields.setDim(0);
577     structsize = 0;
578     alignsize = 0;
579     structalign = 0;
580
581     sc = sc->pop();
582
583     scope = scx ? scx : new Scope(*sc);
584     scope->setNoFree();
585     scope->module->addDeferredSemantic(this);
586
587     //printf("\tsemantic('%s') failed due to forward references\n", toChars());
588     return;
589     }
590
591     //printf("\tsemantic('%s') successful\n", toChars());
592
593     structsize = sc->offset;
594     //members->print();
595
596     /* Look for special member functions.
597      * They must be in this class, not in a base class.
598      */
599     ctor = (CtorDeclaration *)search(0, Id::ctor, 0);
600     if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration()))
601     ctor = NULL;
602
603 //    dtor = (DtorDeclaration *)search(Id::dtor, 0);
604 //    if (dtor && dtor->toParent() != this)
605 //  dtor = NULL;
606
607 //    inv = (InvariantDeclaration *)search(Id::classInvariant, 0);
608 //    if (inv && inv->toParent() != this)
609 //  inv = NULL;
610
611     // Can be in base class
612     aggNew    = (NewDeclaration *)search(0, Id::classNew, 0);
613     aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0);
614
615     // If this class has no constructor, but base class does, create
616     // a constructor:
617     //    this() { }
618     if (!ctor && baseClass && baseClass->ctor)
619     {
620     //printf("Creating default this(){} for class %s\n", toChars());
621     ctor = new