root/branches/dmdfe-2.0/func.c

Revision 914, 71.7 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 <assert.h>
12
13 #include "mars.h"
14 #include "init.h"
15 #include "declaration.h"
16 #include "attrib.h"
17 #include "expression.h"
18 #include "scope.h"
19 #include "mtype.h"
20 #include "aggregate.h"
21 #include "identifier.h"
22 #include "id.h"
23 #include "module.h"
24 #include "statement.h"
25 #include "template.h"
26 #include "hdrgen.h"
27
28 #ifdef IN_GCC
29 #include "d-dmd-gcc.h"
30 #endif
31
32 /********************************* FuncDeclaration ****************************/
33
34 FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
35     : Declaration(id)
36 {
37     //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
38     this->storage_class = storage_class;
39     this->type = type;
40     this->loc = loc;
41     this->endloc = endloc;
42     fthrows = NULL;
43     frequire = NULL;
44     outId = NULL;
45     vresult = NULL;
46     returnLabel = NULL;
47     fensure = NULL;
48     fbody = NULL;
49     localsymtab = NULL;
50     vthis = NULL;
51     v_arguments = NULL;
52 #if IN_GCC
53     v_argptr = NULL;
54 #endif
55     parameters = NULL;
56     labtab = NULL;
57     overnext = NULL;
58     vtblIndex = -1;
59     hasReturnExp = 0;
60     naked = 0;
61     inlineStatus = ILSuninitialized;
62     inlineNest = 0;
63     inlineAsm = 0;
64     cantInterpret = 0;
65     semanticRun = 0;
66     fes = NULL;
67     introducing = 0;
68     tintro = NULL;
69     /* The type given for "infer the return type" is a TypeFunction with
70      * NULL for the return type.
71      */
72     inferRetType = (type && type->nextOf() == NULL);
73     scope = NULL;
74     hasReturnExp = 0;
75     nrvo_can = 1;
76     nrvo_var = NULL;
77     shidden = NULL;
78     builtin = BUILTINunknown;
79     tookAddressOf = 0;
80 }
81
82 Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
83 {
84     FuncDeclaration *f;
85
86     //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
87     if (s)
88     f = (FuncDeclaration *)s;
89     else
90     f = new FuncDeclaration(loc, endloc, ident, (enum STC) storage_class, type->syntaxCopy());
91     f->outId = outId;
92     f->frequire = frequire ? frequire->syntaxCopy() : NULL;
93     f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
94     f->fbody    = fbody    ? fbody->syntaxCopy()    : NULL;
95     assert(!fthrows); // deprecated
96     return f;
97 }
98
99
100 // Do the semantic analysis on the external interface to the function.
101
102 void FuncDeclaration::semantic(Scope *sc)
103 {   TypeFunction *f;
104     StructDeclaration *sd;
105     ClassDeclaration *cd;
106     InterfaceDeclaration *id;
107     Dsymbol *pd;
108
109 #if 0
110     printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
111     if (isFuncLiteralDeclaration())
112     printf("\tFuncLiteralDeclaration()\n");
113     printf("sc->parent = %s\n", sc->parent->toChars());
114     printf("type: %p, %s\n", type, type->toChars());
115 #endif
116
117     storage_class |= sc->stc;
118     //printf("function storage_class = x%x\n", storage_class);
119
120     if (!originalType)
121     originalType = type;
122     if (!type->deco && type->nextOf())
123     {
124 #if 1
125     /* Apply const and invariant storage class
126      * to the function type
127      */
128     type = type->semantic(loc, sc);
129     if (storage_class & STCinvariant)
130     {   // Don't use toInvariant(), as that will do a merge()
131         type = type->makeInvariant();
132         type->deco = type->merge()->deco;
133     }
134     else if (storage_class & STCconst)
135     {
136         if (!type->isInvariant())
137         {   // Don't use toConst(), as that will do a merge()
138         type = type->makeConst();
139         type->deco = type->merge()->deco;
140         }
141     }
142 #else
143     if (storage_class & (STCconst | STCinvariant))
144     {
145         /* Apply const and invariant storage class
146          * to the function's return type
147          */
148         Type *tn = type->nextOf();
149         if (storage_class & STCconst)
150         tn = tn->makeConst();
151         if (storage_class & STCinvariant)
152         tn = tn->makeInvariant();
153         ((TypeNext *)type)->next = tn;
154     }
155
156     type = type->semantic(loc, sc);
157 #endif
158     }
159     //type->print();
160     if (type->ty != Tfunction)
161     {
162     error("%s must be a function", toChars());
163     return;
164     }
165     f = (TypeFunction *)(type);
166
167     size_t nparams = Argument::dim(f->parameters);
168
169     linkage = sc->linkage;
170 //    if (!parent)
171     {
172     //parent = sc->scopesym;
173     parent = sc->parent;
174     }
175     protection = sc->protection;
176     Dsymbol *parent = toParent();
177
178     if (storage_class & STCscope)
179     error("functions cannot be scope");
180
181     if (isAbstract() && !isVirtual())
182     error("non-virtual functions cannot be abstract");
183
184     if ((f->isConst() || f->isInvariant()) && !isThis())
185     error("without 'this' cannot be const/invariant");
186
187     if (isAbstract() && isFinal())
188     error("cannot be both final and abstract");
189 #if 0
190     if (isAbstract() && fbody)
191     error("abstract functions cannot have bodies");
192 #endif
193
194 #if 0
195     if (isStaticConstructor() || isStaticDestructor())
196     {
197     if (!isStatic() || type->nextOf()->ty != Tvoid)
198         error("static constructors / destructors must be static void");
199     if (f->arguments && f->arguments->dim)
200         error("static constructors / destructors must have empty parameter list");
201     // BUG: check for invalid storage classes
202     }
203 #endif
204
205 #ifdef IN_GCC
206     AggregateDeclaration *ad;
207
208     ad = parent->isAggregateDeclaration();
209     if (ad)
210     ad->methods.push(this);
211 #endif
212     sd = parent->isStructDeclaration();
213     if (sd)
214     {
215     if (isCtorDeclaration())
216     {
217         return;
218     }
219 #if 0
220     // Verify no constructors, destructors, etc.
221     if (isCtorDeclaration()
222         //||isDtorDeclaration()
223         //|| isInvariantDeclaration()
224         //|| isUnitTestDeclaration()
225        )
226     {
227         error("special member functions not allowed for %ss", sd->kind());
228     }
229
230     if (!sd->inv)
231         sd->inv = isInvariantDeclaration();
232
233     if (!sd->aggNew)
234         sd->aggNew = isNewDeclaration();
235
236     if (isDelete())
237     {
238         if (sd->aggDelete)
239         error("multiple delete's for struct %s", sd->toChars());
240         sd->aggDelete = (DeleteDeclaration *)(this);
241     }
242 #endif
243     }
244
245     id = parent->isInterfaceDeclaration();
246     if (id)
247     {
248     storage_class |= STCabstract;
249
250     if (isCtorDeclaration() ||
251         isPostBlitDeclaration() ||
252         isDtorDeclaration() ||
253         isInvariantDeclaration() ||
254         isUnitTestDeclaration() || isNewDeclaration() || isDelete())
255         error("special function not allowed in interface %s", id->toChars());
256     if (fbody)
257         error("function body is not abstract in interface %s", id->toChars());
258     }
259
260     /* Template member functions aren't virtual:
261      *   interface TestInterface { void tpl(T)(); }
262      * and so won't work in interfaces
263      */
264     if ((pd = toParent()) != NULL &&
265     pd->isTemplateInstance() &&
266     (pd = toParent2()) != NULL &&
267     (id = pd->isInterfaceDeclaration()) != NULL)
268     {
269     error("template member function not allowed in interface %s", id->toChars());
270     }
271
272     cd = parent->isClassDeclaration();
273     if (cd)
274     {   int vi;
275     CtorDeclaration *ctor;
276     DtorDeclaration *dtor;
277     InvariantDeclaration *inv;
278
279     if (isCtorDeclaration())
280     {
281 //      ctor = (CtorDeclaration *)this;
282 //      if (!cd->ctor)
283 //      cd->ctor = ctor;
284         return;
285     }
286
287 #if 0
288     dtor = isDtorDeclaration();
289     if (dtor)
290     {
291         if (cd->dtor)
292         error("multiple destructors for class %s", cd->toChars());
293         cd->dtor = dtor;
294     }
295
296     inv = isInvariantDeclaration();
297     if (inv)
298     {
299         cd->inv = inv;
300     }
301
302     if (isNewDeclaration())
303     {
304         if (!cd->aggNew)
305         cd->aggNew = (NewDeclaration *)(this);
306     }
307
308     if (isDelete())
309     {
310         if (cd->aggDelete)
311         error("multiple delete's for class %s", cd->toChars());
312         cd->aggDelete = (DeleteDeclaration *)(this);
313     }
314 #endif
315
316     if (storage_class & STCabstract)
317         cd->isabstract = 1;
318
319     // if static function, do not put in vtbl[]
320     if (!isVirtual())
321     {
322         //printf("\tnot virtual\n");
323         goto Ldone;
324     }
325
326     // Find index of existing function in vtbl[] to override
327     vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0);
328     switch (vi)
329     {
330         case -1:
331         /* Didn't find one, so
332          * This is an 'introducing' function which gets a new
333          * slot in the vtbl[].
334          */
335
336         // Verify this doesn't override previous final function
337         if (cd->baseClass)
338         {   Dsymbol *s = cd->baseClass->search(loc, ident, 0);
339             if (s)
340             {
341             FuncDeclaration *f = s->isFuncDeclaration();
342             f = f->overloadExactMatch(type);
343             if (f && f->isFinal() && f->prot() != PROTprivate)
344                 error("cannot override final function %s", f->toPrettyChars());
345             }
346         }
347
348         if (isFinal())
349         {
350             cd->vtblFinal.push(this);
351         }
352         else
353         {
354             // Append to end of vtbl[]
355             //printf("\tintroducing function\n");
356             introducing = 1;
357             vi = cd->vtbl.dim;
358             cd->vtbl.push(this);
359             vtblIndex = vi;
360         }
361         break;
362
363         case -2:    // can't determine because of fwd refs
364         cd->sizeok = 2; // can't finish due to forward reference
365         return;
366
367         default:
368         {   FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi];
369         // This function is covariant with fdv
370         if (fdv->isFinal())
371             error("cannot override final function %s", fdv->toPrettyChars());
372
373 #if V2
374         if (!isOverride() && global.params.warnings)
375             error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
376 #endif
377
378         if (fdv->toParent() == parent)
379         {
380             // If both are mixins, then error.
381             // If either is not, the one that is not overrides
382             // the other.
383             if (fdv->parent->isClassDeclaration())
384             break;
385             if (!this->parent->isClassDeclaration()
386 #if !BREAKABI
387             && !isDtorDeclaration()
388 #endif
389 #if V2
390             && !isPostBlitDeclaration()
391 #endif
392             )
393             error("multiple overrides of same function");
394         }
395         cd->vtbl.data[vi] = (void *)this;
396         vtblIndex = vi;
397
398         /* This works by whenever this function is called,
399          * it actually returns tintro, which gets dynamically
400          * cast to type. But we know that tintro is a base
401          * of type, so we could optimize it by not doing a
402          * dynamic cast, but just subtracting the isBaseOf()
403          * offset if the value is != null.
404          */
405
406         if (fdv->tintro)
407             tintro = fdv->tintro;
408         else if (!type->equals(fdv->type))
409         {
410             /* Only need to have a tintro if the vptr
411              * offsets differ
412              */
413             int offset;
414             if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
415             {
416             tintro = fdv->type;
417             }
418         }
419         break;
420         }
421     }
422
423     /* Go through all the interface bases.
424      * If this function is covariant with any members of those interface
425      * functions, set the tintro.
426      */
427     for (int i = 0; i < cd->interfaces_dim; i++)
428     {
429         BaseClass *b = cd->interfaces[i];
430         vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim);
431         switch (vi)
432         {
433         case -1:
434             break;
435
436         case -2:
437             cd->sizeok = 2; // can't finish due to forward reference
438             return;
439
440         default:
441         {   FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi];
442             Type *ti = NULL;
443
444             if (fdv->tintro)
445             ti = fdv->tintro;
446             else if (!type->equals(fdv->type))
447             {
448             /* Only need to have a tintro if the vptr
449              * offsets differ
450              */
451             int offset;
452             if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
453             {
454                 ti = fdv->type;
455 #if 0
456                 if (offset)
457                 ti = fdv->type;
458                 else if (type->nextOf()->ty == Tclass)
459                 {   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
460                 if (cdn && cdn->sizeok != 1)
461                     ti = fdv->type;
462                 }
463 #endif
464             }
465             }
466             if (ti)
467             {
468             if (tintro && !tintro->equals(ti))
469             {
470                 error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
471             }
472             tintro = ti;
473             }
474             goto L2;
475         }
476         }
477     }
478
479     if (introducing && isOverride())
480     {
481         error("does not override any function");
482     }
483
484     L2: ;
485     }
486     else if (isOverride() && !parent->isTemplateInstance())
487     error("override only applies to class member functions");
488
489     /* Do not allow template instances to add virtual functions
490      * to a class.
491      */
492     if (isVirtual())
493     {
494     TemplateInstance *ti = parent->isTemplateInstance();
495     if (ti)
496     {
497         // Take care of nested templates
498         while (1)
499         {
500         TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
501         if (!ti2)
502             break;
503         ti = ti2;
504         }
505
506         // If it's a member template
507         ClassDeclaration *cd = ti->tempdecl->isClassMember();
508         if (cd)
509         {
510         error("cannot use template to add virtual function to class '%s'", cd->toChars());
511         }
512     }
513     }
514
515     if (isMain())
516     {
517     // Check parameters to see if they are either () or (char[][] args)
518     switch (nparams)
519     {
520         case 0:
521         break;
522
523         case 1:
524         {
525         Argument *arg0 = Argument::getNth(f->parameters, 0);
526         if (arg0->type->ty != Tarray ||
527             arg0->type->nextOf()->ty != Tarray ||
528             arg0->type->nextOf()->nextOf()->ty != Tchar ||
529             arg0->storageClass & (STCout | STCref | STClazy))
530             goto Lmainerr;
531         break;
532         }
533
534         default:
535         goto Lmainerr;
536     }
537
538     if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid)
539         error("must return int or void, not %s", f->nextOf()->toChars());
540     if (f->varargs)
541     {
542     Lmainerr:
543         error("parameters must be main() or main(char[][] args)");
544     }
545     }
546
547     if (ident == Id::assign && (sd || cd))
548     {   // Disallow identity assignment operator.
549
550     // opAssign(...)
551     if (nparams == 0)
552     {   if (f->varargs == 1)
553         goto Lassignerr;
554     }
555     else
556     {
557         Argument *arg0 = Argument::getNth(f->parameters, 0);
558         Type *t0 = arg0->type->toBasetype();
559         Type *tb = sd ? sd->type : cd->type;
560         if (arg0->type->implicitConvTo(tb) ||
561         (sd && t0->ty == Tpointer && t0->nextOf()->implicitConvTo(tb))
562            )
563         {
564         if (nparams == 1)
565             goto Lassignerr;
566         Argument *arg1 = Argument::getNth(f->parameters, 1);
567         if (arg1->defaultArg)
568             goto Lassignerr;
569         }
570     }
571     }
572
573 Ldone:
574     /* Save scope for possible later use (if we need the
575      * function internals)
576      */
577     scope = new Scope(*sc);
578     scope->setNoFree();
579     return;
580
581 Lassignerr:
582     if (sd)
583     {
584     sd->hasIdentityAssign = 1;  // don't need to generate it
585     goto Ldone;
586     }
587     error("identity assignment operator overload is illegal");
588 }
589
590 void FuncDeclaration::semantic2(Scope *sc)
591 {
592 }
593
594 // Do the semantic analysis on the internals of the function.
595
596 void FuncDeclaration::semantic3(Scope *sc)
597 {   TypeFunction *f;
598     AggregateDeclaration *ad;
599     VarDeclaration *argptr = NULL;
600     VarDeclaration *_arguments = NULL;
601
602     if (!parent)
603     {
604     if (global.errors)
605         return;
606     //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
607     assert(0);
608     }
609     //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
610     //fflush(stdout);
611     //{ static int x; if (++x == 2) *(char*)0=0; }
612     //printf("\tlinkage = %d\n", sc->linkage);
613
614     //printf(" sc->incontract = %d\n", sc->incontract);
615     if (semanticRun)
616     return;
617     semanticRun = 1;
618
619     if (!type || type->ty != Tfunction)
620     return;
621     f = (TypeFunction *)(type);
622
623     // Check the 'throws' clause
624     if (fthrows)
625     {
626     for (int i = 0; i < fthrows->dim; i++)
627     {
628         Type *t = (Type *)fthrows->data[i];
629
630         t = t->semantic(loc, sc);
631         if (!t->isClassHandle())
632         error("can only throw classes, not %s", t->toChars());
633     }
634     }
635
636     if (fbody || frequire)
637     {
638     /* Symbol table into which we place parameters and nested functions,
639      * solely to diagnose name collisions.
640      */
641     localsymtab = new DsymbolTable();
642
643     // Establish function scope
644     ScopeDsymbol *ss = new ScopeDsymbol();
645     ss->parent = sc->scopesym;
646     Scope *sc2 = sc->push(ss);
647     sc2->func = this;
648     sc2->parent = this;
649     sc2->callSuper = 0;
650     sc2->sbreak = NULL;
651     sc2->scontinue = NULL;
652     sc2->sw = NULL;
653     sc2->fes = fes;
654     sc2->linkage = LINKd;
655     sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls);
656     sc2->protection = PROTpublic;
657     sc2->explicitProtection = 0;
658     sc2->structalign = 8;
659     sc2->incontract = 0;
660     sc2->tf = NULL;
661     sc2->noctor = 0;
662
663     // Declare 'this'
664     ad = isThis();
665     if (ad)
666     {   VarDeclaration *v;
667
668         if (isFuncLiteralDeclaration() && isNested())
669         {
670         error("literals cannot be class members");
671         return;
672         }
673         else
674         {
675         assert(!isNested());    // can't be both member and nested
676         assert(ad->handle);
677         Type *thandle = ad->handle;
678         if (storage_class & STCconst || type->isConst())
679         {
680             if (thandle->ty == Tclass)
681             thandle = thandle->constOf();
682             else
683             {   assert(thandle->ty == Tpointer);
684             thandle = thandle->nextOf()->constOf()->pointerTo();
685             }
686         }
687         else if (storage_class & STCinvariant || type->