1
2/* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/func.c
9 */
10
11#include "root/dsystem.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#include "target.h"
28#include "parse.h"
29#include "root/rmem.h"
30#include "visitor.h"
31#include "objc.h"
32
33Expression *addInvariant(Loc loc, Scope *sc, AggregateDeclaration *ad, VarDeclaration *vthis, bool direct);
34bool checkReturnEscape(Scope *sc, Expression *e, bool gag);
35bool checkReturnEscapeRef(Scope *sc, Expression *e, bool gag);
36bool checkNestedRef(Dsymbol *s, Dsymbol *p);
37Statement *semantic(Statement *s, Scope *sc);
38void semantic(Catch *c, Scope *sc);
39Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
40Expression *semantic(Expression *e, Scope *sc);
41int blockExit(Statement *s, FuncDeclaration *func, bool mustNotThrow);
42TypeIdentifier *getThrowable();
43
44RET retStyle(TypeFunction *tf);
45void MODtoBuffer(OutBuffer *buf, MOD mod);
46char *MODtoChars(MOD mod);
47bool MODimplicitConv(MOD modfrom, MOD modto);
48MATCH MODmethodConv(MOD modfrom, MOD modto);
49void allocFieldinit(Scope *sc, size_t dim);
50void freeFieldinit(Scope *sc);
51Objc *objc();
52
53
54/* A visitor to walk entire statements and provides ability to replace any sub-statements.
55 */
56class StatementRewriteWalker : public Visitor
57{
58    /* Point the currently visited statement.
59     * By using replaceCurrent() method, you can replace AST during walking.
60     */
61    Statement **ps;
62public:
63    void visitStmt(Statement *&s) { ps = &s; s->accept(this); }
64    void replaceCurrent(Statement *s) { *ps = s; }
65
66    void visit(ErrorStatement *) {  }
67    void visit(PeelStatement *s)
68    {
69        if (s->s)
70            visitStmt(s->s);
71    }
72    void visit(ExpStatement *) {  }
73    void visit(DtorExpStatement *) {  }
74    void visit(CompileStatement *) {  }
75    void visit(CompoundStatement *s)
76    {
77        if (s->statements && s->statements->dim)
78        {
79            for (size_t i = 0; i < s->statements->dim; i++)
80            {
81                if ((*s->statements)[i])
82                    visitStmt((*s->statements)[i]);
83            }
84        }
85    }
86    void visit(CompoundDeclarationStatement *s) { visit((CompoundStatement *)s); }
87    void visit(UnrolledLoopStatement *s)
88    {
89        if (s->statements && s->statements->dim)
90        {
91            for (size_t i = 0; i < s->statements->dim; i++)
92            {
93                if ((*s->statements)[i])
94                    visitStmt((*s->statements)[i]);
95            }
96        }
97    }
98    void visit(ScopeStatement *s)
99    {
100        if (s->statement)
101            visitStmt(s->statement);
102    }
103    void visit(WhileStatement *s)
104    {
105        if (s->_body)
106            visitStmt(s->_body);
107    }
108    void visit(DoStatement *s)
109    {
110        if (s->_body)
111            visitStmt(s->_body);
112    }
113    void visit(ForStatement *s)
114    {
115        if (s->_init)
116            visitStmt(s->_init);
117        if (s->_body)
118            visitStmt(s->_body);
119    }
120    void visit(ForeachStatement *s)
121    {
122        if (s->_body)
123            visitStmt(s->_body);
124    }
125    void visit(ForeachRangeStatement *s)
126    {
127        if (s->_body)
128            visitStmt(s->_body);
129    }
130    void visit(IfStatement *s)
131    {
132        if (s->ifbody)
133            visitStmt(s->ifbody);
134        if (s->elsebody)
135            visitStmt(s->elsebody);
136    }
137    void visit(ConditionalStatement *) {  }
138    void visit(PragmaStatement *) {  }
139    void visit(StaticAssertStatement *) {  }
140    void visit(SwitchStatement *s)
141    {
142        if (s->_body)
143            visitStmt(s->_body);
144    }
145    void visit(CaseStatement *s)
146    {
147        if (s->statement)
148            visitStmt(s->statement);
149    }
150    void visit(CaseRangeStatement *s)
151    {
152        if (s->statement)
153            visitStmt(s->statement);
154    }
155    void visit(DefaultStatement *s)
156    {
157        if (s->statement)
158            visitStmt(s->statement);
159    }
160    void visit(GotoDefaultStatement *) {  }
161    void visit(GotoCaseStatement *) {  }
162    void visit(SwitchErrorStatement *) {  }
163    void visit(ReturnStatement *) {  }
164    void visit(BreakStatement *) {  }
165    void visit(ContinueStatement *) {  }
166    void visit(SynchronizedStatement *s)
167    {
168        if (s->_body)
169            visitStmt(s->_body);
170    }
171    void visit(WithStatement *s)
172    {
173        if (s->_body)
174            visitStmt(s->_body);
175    }
176    void visit(TryCatchStatement *s)
177    {
178        if (s->_body)
179            visitStmt(s->_body);
180        if (s->catches && s->catches->dim)
181        {
182            for (size_t i = 0; i < s->catches->dim; i++)
183            {
184                Catch *c = (*s->catches)[i];
185                if (c && c->handler)
186                    visitStmt(c->handler);
187            }
188        }
189    }
190    void visit(TryFinallyStatement *s)
191    {
192        if (s->_body)
193            visitStmt(s->_body);
194        if (s->finalbody)
195            visitStmt(s->finalbody);
196    }
197    void visit(OnScopeStatement *) {  }
198    void visit(ThrowStatement *) {  }
199    void visit(DebugStatement *s)
200    {
201        if (s->statement)
202            visitStmt(s->statement);
203    }
204    void visit(GotoStatement *) {  }
205    void visit(LabelStatement *s)
206    {
207        if (s->statement)
208            visitStmt(s->statement);
209    }
210    void visit(AsmStatement *) {  }
211    void visit(ImportStatement *) {  }
212};
213
214/* Tweak all return statements and dtor call for nrvo_var, for correct NRVO.
215 */
216class NrvoWalker : public StatementRewriteWalker
217{
218public:
219    FuncDeclaration *fd;
220    Scope *sc;
221
222    void visit(ReturnStatement *s)
223    {
224        // See if all returns are instead to be replaced with a goto returnLabel;
225        if (fd->returnLabel)
226        {
227            /* Rewrite:
228             *  return exp;
229             * as:
230             *  vresult = exp; goto Lresult;
231             */
232            GotoStatement *gs = new GotoStatement(s->loc, Id::returnLabel);
233            gs->label = fd->returnLabel;
234
235            Statement *s1 = gs;
236            if (s->exp)
237                s1 = new CompoundStatement(s->loc, new ExpStatement(s->loc, s->exp), gs);
238
239            replaceCurrent(s1);
240        }
241    }
242    void visit(TryFinallyStatement *s)
243    {
244        DtorExpStatement *des;
245        if (fd->nrvo_can &&
246            s->finalbody && (des = s->finalbody->isDtorExpStatement()) != NULL &&
247            fd->nrvo_var == des->var)
248        {
249            if (!(global.params.useExceptions && ClassDeclaration::throwable))
250            {
251                /* Don't need to call destructor at all, since it is nrvo
252                 */
253                replaceCurrent(s->_body);
254                s->_body->accept(this);
255                return;
256            }
257
258            /* Normally local variable dtors are called regardless exceptions.
259             * But for nrvo_var, its dtor should be called only when exception is thrown.
260             *
261             * Rewrite:
262             *      try { s->body; } finally { nrvo_var->edtor; }
263             *      // equivalent with:
264             *      //    s->body; scope(exit) nrvo_var->edtor;
265             * as:
266             *      try { s->body; } catch(Throwable __o) { nrvo_var->edtor; throw __o; }
267             *      // equivalent with:
268             *      //    s->body; scope(failure) nrvo_var->edtor;
269             */
270            Statement *sexception = new DtorExpStatement(Loc(), fd->nrvo_var->edtor, fd->nrvo_var);
271            Identifier *id = Identifier::generateId("__o");
272
273            Statement *handler = new PeelStatement(sexception);
274            if (blockExit(sexception, fd, false) & BEfallthru)
275            {
276                ThrowStatement *ts = new ThrowStatement(Loc(), new IdentifierExp(Loc(), id));
277                ts->internalThrow = true;
278                handler = new CompoundStatement(Loc(), handler, ts);
279            }
280
281            Catches *catches = new Catches();
282            Catch *ctch = new Catch(Loc(), getThrowable(), id, handler);
283            ctch->internalCatch = true;
284            ::semantic(ctch, sc);     // Run semantic to resolve identifier '__o'
285            catches->push(ctch);
286
287            Statement *s2 = new TryCatchStatement(Loc(), s->_body, catches);
288            replaceCurrent(s2);
289            s2->accept(this);
290        }
291        else
292            StatementRewriteWalker::visit(s);
293    }
294};
295
296/********************************* FuncDeclaration ****************************/
297
298FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
299    : Declaration(id)
300{
301    //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
302    //printf("storage_class = x%x\n", storage_class);
303    this->storage_class = storage_class;
304    this->type = type;
305    if (type)
306    {
307        // Normalize storage_class, because function-type related attributes
308        // are already set in the 'type' in parsing phase.
309        this->storage_class &= ~(STC_TYPECTOR | STC_FUNCATTR);
310    }
311    this->loc = loc;
312    this->endloc = endloc;
313    fthrows = NULL;
314    frequire = NULL;
315    fdrequire = NULL;
316    fdensure = NULL;
317    mangleString = NULL;
318    outId = NULL;
319    vresult = NULL;
320    returnLabel = NULL;
321    fensure = NULL;
322    fbody = NULL;
323    localsymtab = NULL;
324    vthis = NULL;
325    v_arguments = NULL;
326    v_argptr = NULL;
327    parameters = NULL;
328    labtab = NULL;
329    overnext = NULL;
330    overnext0 = NULL;
331    vtblIndex = -1;
332    hasReturnExp = 0;
333    naked = false;
334    generated = false;
335    inlineStatusExp = ILSuninitialized;
336    inlineStatusStmt = ILSuninitialized;
337    inlining = PINLINEdefault;
338    inlineNest = 0;
339    ctfeCode = NULL;
340    isArrayOp = 0;
341    semantic3Errors = false;
342    fes = NULL;
343    interfaceVirtual = NULL;
344    introducing = 0;
345    tintro = NULL;
346    /* The type given for "infer the return type" is a TypeFunction with
347     * NULL for the return type.
348     */
349    inferRetType = (type && type->nextOf() == NULL);
350    storage_class2 = 0;
351    hasReturnExp = 0;
352    nrvo_can = 1;
353    nrvo_var = NULL;
354    shidden = NULL;
355    builtin = BUILTINunknown;
356    tookAddressOf = 0;
357    requiresClosure = false;
358    inlinedNestedCallees = NULL;
359    flags = 0;
360    returns = NULL;
361    gotos = NULL;
362    selector = NULL;
363}
364
365FuncDeclaration *FuncDeclaration::create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
366{
367    return new FuncDeclaration(loc, endloc, id, storage_class, type);
368}
369
370Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
371{
372    //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
373    FuncDeclaration *f =
374        s ? (FuncDeclaration *)s
375          : new FuncDeclaration(loc, endloc, ident, storage_class, type->syntaxCopy());
376    f->outId = outId;
377    f->frequire = frequire ? frequire->syntaxCopy() : NULL;
378    f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
379    f->fbody    = fbody    ? fbody->syntaxCopy()    : NULL;
380    assert(!fthrows); // deprecated
381    return f;
382}
383
384/**********************************
385 * Decide if attributes for this function can be inferred from examining
386 * the function body.
387 * Returns:
388 *  true if can
389 */
390static bool canInferAttributes(FuncDeclaration *fd, Scope *sc)
391{
392    if (!fd->fbody)
393        return false;
394
395    if (fd->isVirtualMethod())
396        return false;               // since they may be overridden
397
398    if (sc->func &&
399        /********** this is for backwards compatibility for the moment ********/
400        (!fd->isMember() || (sc->func->isSafeBypassingInference() && !fd->isInstantiated())))
401        return true;
402
403    if (fd->isFuncLiteralDeclaration() ||               // externs are not possible with literals
404        (fd->storage_class & STCinference) ||           // do attribute inference
405        (fd->inferRetType && !fd->isCtorDeclaration()))
406        return true;
407
408    if (fd->isInstantiated())
409    {
410        TemplateInstance *ti = fd->parent->isTemplateInstance();
411        if (ti == NULL || ti->isTemplateMixin() || ti->tempdecl->ident == fd->ident)
412            return true;
413    }
414
415    return false;
416}
417
418/*****************************************
419 * Initialize for inferring the attributes of this function.
420 */
421static void initInferAttributes(FuncDeclaration *fd)
422{
423    //printf("initInferAttributes() for %s\n", toPrettyChars());
424    TypeFunction *tf = fd->type->toTypeFunction();
425    if (tf->purity == PUREimpure) // purity not specified
426        fd->flags |= FUNCFLAGpurityInprocess;
427
428    if (tf->trust == TRUSTdefault)
429        fd->flags |= FUNCFLAGsafetyInprocess;
430
431    if (!tf->isnothrow)
432        fd->flags |= FUNCFLAGnothrowInprocess;
433
434    if (!tf->isnogc)
435        fd->flags |= FUNCFLAGnogcInprocess;
436
437    if (!fd->isVirtual() || fd->introducing)
438        fd->flags |= FUNCFLAGreturnInprocess;
439
440    // Initialize for inferring STCscope
441    if (global.params.vsafe)
442        fd->flags |= FUNCFLAGinferScope;
443}
444
445// Do the semantic analysis on the external interface to the function.
446
447void FuncDeclaration::semantic(Scope *sc)
448{
449    TypeFunction *f;
450    AggregateDeclaration *ad;
451    InterfaceDeclaration *id;
452
453    if (semanticRun != PASSinit && isFuncLiteralDeclaration())
454    {
455        /* Member functions that have return types that are
456         * forward references can have semantic() run more than
457         * once on them.
458         * See test\interface2.d, test20
459         */
460        return;
461    }
462
463    if (semanticRun >= PASSsemanticdone)
464        return;
465    assert(semanticRun <= PASSsemantic);
466    semanticRun = PASSsemantic;
467
468    if (_scope)
469    {
470        sc = _scope;
471        _scope = NULL;
472    }
473
474    if (!sc || errors)
475        return;
476
477    parent = sc->parent;
478    Dsymbol *parent = toParent();
479
480    foverrides.setDim(0);       // reset in case semantic() is being retried for this function
481
482    storage_class |= sc->stc & ~STCref;
483    ad = isThis();
484    // Don't nest structs b/c of generated methods which should not access the outer scopes.
485    // https://issues.dlang.org/show_bug.cgi?id=16627
486    if (ad && !generated)
487    {
488        storage_class |= ad->storage_class & (STC_TYPECTOR | STCsynchronized);
489        ad->makeNested();
490    }
491    if (sc->func)
492        storage_class |= sc->func->storage_class & STCdisable;
493    // Remove prefix storage classes silently.
494    if ((storage_class & STC_TYPECTOR) && !(ad || isNested()))
495        storage_class &= ~STC_TYPECTOR;
496
497    //printf("function storage_class = x%llx, sc->stc = x%llx, %x\n", storage_class, sc->stc, Declaration::isFinal());
498
499    FuncLiteralDeclaration *fld = isFuncLiteralDeclaration();
500    if (fld && fld->treq)
501    {
502        Type *treq = fld->treq;
503        assert(treq->nextOf()->ty == Tfunction);
504        if (treq->ty == Tdelegate)
505            fld->tok = TOKdelegate;
506        else if (treq->ty == Tpointer && treq->nextOf()->ty == Tfunction)
507            fld->tok = TOKfunction;
508        else
509            assert(0);
510        linkage = treq->nextOf()->toTypeFunction()->linkage;
511    }
512    else
513        linkage = sc->linkage;
514    inlining = sc->inlining;
515    protection = sc->protection;
516    userAttribDecl = sc->userAttribDecl;
517
518    if (!originalType)
519        originalType = type->syntaxCopy();
520    if (type->ty != Tfunction)
521    {
522        if (type->ty != Terror)
523        {
524            error("%s must be a function instead of %s", toChars(), type->toChars());
525            type = Type::terror;
526        }
527        errors = true;
528        return;
529    }
530    if (!type->deco)
531    {
532        sc = sc->push();
533        sc->stc |= storage_class & (STCdisable | STCdeprecated);  // forward to function type
534        TypeFunction *tf = type->toTypeFunction();
535
536        if (sc->func)
537        {
538            /* If the nesting parent is pure without inference,
539             * then this function defaults to pure too.
540             *
541             *  auto foo() pure {
542             *    auto bar() {}     // become a weak purity funciton
543             *    class C {         // nested class
544             *      auto baz() {}   // become a weak purity funciton
545             *    }
546             *
547             *    static auto boo() {}   // typed as impure
548             *    // Even though, boo cannot call any impure functions.
549             *    // See also Expression::checkPurity().
550             *  }
551             */
552            if (tf->purity == PUREimpure && (isNested() || isThis()))
553            {
554                FuncDeclaration *fd = NULL;
555                for (Dsymbol *p = toParent2(); p; p = p->toParent2())
556                {
557                    if (AggregateDeclaration *adx = p->isAggregateDeclaration())
558                    {
559                        if (adx->isNested())
560                            continue;
561                        break;
562                    }
563                    if ((fd = p->isFuncDeclaration()) != NULL)
564                        break;
565                }
566
567                /* If the parent's purity is inferred, then this function's purity needs
568                 * to be inferred first.
569                 */
570                if (fd && fd->isPureBypassingInference() >= PUREweak &&
571                    !isInstantiated())
572                {
573                    tf->purity = PUREfwdref;            // default to pure
574                }
575            }
576        }
577
578        if (tf->isref)      sc->stc |= STCref;
579        if (tf->isscope)    sc->stc |= STCscope;
580        if (tf->isnothrow)  sc->stc |= STCnothrow;
581        if (tf->isnogc)     sc->stc |= STCnogc;
582        if (tf->isproperty) sc->stc |= STCproperty;
583        if (tf->purity == PUREfwdref)   sc->stc |= STCpure;
584        if (tf->trust != TRUSTdefault)
585            sc->stc &= ~(STCsafe | STCsystem | STCtrusted);
586        if (tf->trust == TRUSTsafe)     sc->stc |= STCsafe;
587        if (tf->trust == TRUSTsystem)   sc->stc |= STCsystem;
588        if (tf->trust == TRUSTtrusted)  sc->stc |= STCtrusted;
589
590        if (isCtorDeclaration())
591        {
592            sc->flags |= SCOPEctor;
593
594            Type *tret = ad->handleType();
595            assert(tret);
596            tret = tret->addStorageClass(storage_class | sc->stc);
597            tret = tret->addMod(type->mod);
598            tf->next = tret;
599
600            if (ad->isStructDeclaration())
601                sc->stc |= STCref;
602        }
603
604        // 'return' on a non-static class member function implies 'scope' as well
605        if (ad && ad->isClassDeclaration() && (tf->isreturn || sc->stc & STCreturn) && !(sc->stc & STCstatic))
606            sc->stc |= STCscope;
607
608        // If 'this' has no pointers, remove 'scope' as it has no meaning
609        if (sc->stc & STCscope && ad && ad->isStructDeclaration() && !ad->type->hasPointers())
610        {
611            sc->stc &= ~STCscope;
612            tf->isscope = false;
613        }
614
615        sc->linkage = linkage;
616
617        if (!tf->isNaked() && !(isThis() || isNested()))
618        {
619            OutBuffer buf;
620            MODtoBuffer(&buf, tf->mod);
621            error("without 'this' cannot be %s", buf.peekString());
622            tf->mod = 0;    // remove qualifiers
623        }
624
625        /* Apply const, immutable, wild and shared storage class
626         * to the function type. Do this before type semantic.
627         */
628        StorageClass stc = storage_class;
629        if (type->isImmutable())
630            stc |= STCimmutable;
631        if (type->isConst())
632            stc |= STCconst;
633        if (type->isShared() || storage_class & STCsynchronized)
634            stc |= STCshared;
635        if (type->isWild())
636            stc |= STCwild;
637        switch (stc & STC_TYPECTOR)
638        {
639            case STCimmutable:
640            case STCimmutable | STCconst:
641            case STCimmutable | STCwild:
642            case STCimmutable | STCwild | STCconst:
643            case STCimmutable | STCshared:
644            case STCimmutable | STCshared | STCconst:
645            case STCimmutable | STCshared | STCwild:
646            case STCimmutable | STCshared | STCwild | STCconst:
647                // Don't use immutableOf(), as that will do a merge()
648                type = type->makeImmutable();
649                break;
650
651            case STCconst:
652                type = type->makeConst();
653                break;
654
655            case STCwild:
656                type = type->makeWild();
657                break;
658
659            case STCwild | STCconst:
660                type = type->makeWildConst();
661                break;
662
663            case STCshared:
664                type = type->makeShared();
665                break;
666
667            case STCshared | STCconst:
668                type = type->makeSharedConst();
669                break;
670
671            case STCshared | STCwild:
672                type = type->makeSharedWild();
673                break;
674
675            case STCshared | STCwild | STCconst:
676                type = type->makeSharedWildConst();
677                break;
678
679            case 0:
680                break;
681
682            default:
683                assert(0);
684        }
685
686        type = type->semantic(loc, sc);
687        sc = sc->pop();
688    }
689    if (type->ty != Tfunction)
690    {
691        if (type->ty != Terror)
692        {
693            error("%s must be a function instead of %s", toChars(), type->toChars());
694            type = Type::terror;
695        }
696        errors = true;
697        return;
698    }
699    else
700    {
701        // Merge back function attributes into 'originalType'.
702        // It's used for mangling, ddoc, and json output.
703        TypeFunction *tfo = originalType->toTypeFunction();
704        TypeFunction *tfx = type->toTypeFunction();
705        tfo->mod        = tfx->mod;
706        tfo->isscope    = tfx->isscope;
707        tfo->isscopeinferred = tfx->isscopeinferred;
708        tfo->isref      = tfx->isref;
709        tfo->isnothrow  = tfx->isnothrow;
710        tfo->isnogc     = tfx->isnogc;
711        tfo->isproperty = tfx->isproperty;
712        tfo->purity     = tfx->purity;
713        tfo->trust      = tfx->trust;
714
715        storage_class &= ~(STC_TYPECTOR | STC_FUNCATTR);
716    }
717
718    f = (TypeFunction *)type;
719
720    if ((storage_class & STCauto) && !f->isref && !inferRetType)
721        error("storage class 'auto' has no effect if return type is not inferred");
722    /* Functions can only be 'scope' if they have a 'this'
723     */
724    if (f->isscope && !isNested() && !ad)
725    {
726        error("functions cannot be scope");
727    }
728
729    if (f->isreturn && !needThis() && !isNested())
730    {
731        /* Non-static nested functions have a hidden 'this' pointer to which
732         * the 'return' applies
733         */
734        error("static member has no 'this' to which 'return' can apply");
735    }
736
737    if (isAbstract() && !isVirtual())
738    {
739        const char *sfunc;
740        if (isStatic())
741            sfunc = "static";
742        else if (protection.kind == PROTprivate || protection.kind == PROTpackage)
743            sfunc = protectionToChars(protection.kind);
744        else
745            sfunc = "non-virtual";
746        error("%s functions cannot be abstract", sfunc);
747    }
748
749    if (isOverride() && !isVirtual())
750    {
751        PROTKIND kind = prot().kind;
752        if ((kind == PROTprivate || kind == PROTpackage) && isMember())
753            error("%s method is not virtual and cannot override", protectionToChars(kind));
754        else
755            error("cannot override a non-virtual function");
756    }
757
758    if (isAbstract() && isFinalFunc())
759        error("cannot be both final and abstract");
760
761    id = parent->isInterfaceDeclaration();
762    if (id)
763    {
764        storage_class |= STCabstract;
765
766        if (isCtorDeclaration() ||
767            isPostBlitDeclaration() ||
768            isDtorDeclaration() ||
769            isInvariantDeclaration() ||
770            isNewDeclaration() || isDelete())
771            error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface %s", id->toChars());
772        if (fbody && isVirtual())
773            error("function body only allowed in final functions in interface %s", id->toChars());
774    }
775
776    if (UnionDeclaration *ud = parent->isUnionDeclaration())
777    {
778        if (isPostBlitDeclaration() ||
779            isDtorDeclaration() ||
780            isInvariantDeclaration())
781            error("destructors, postblits and invariants are not allowed in union %s", ud->toChars());
782    }
783
784    /* Contracts can only appear without a body when they are virtual interface functions
785     */
786    if (!fbody && (fensure || frequire) && !(id && isVirtual()))
787        error("in and out contracts require function body");
788
789    if (parent->isStructDeclaration())
790    {
791        if (isCtorDeclaration())
792        {
793            goto Ldone;
794        }
795    }
796
797    if (ClassDeclaration *cd = parent->isClassDeclaration())
798    {
799        if (isCtorDeclaration())
800        {
801            goto Ldone;
802        }
803
804        if (storage_class & STCabstract)
805            cd->isabstract = ABSyes;
806
807        // if static function, do not put in vtbl[]
808        if (!isVirtual())
809        {
810            //printf("\tnot virtual\n");
811            goto Ldone;
812        }
813        // Suppress further errors if the return type is an error
814        if (type->nextOf() == Type::terror)
815            goto Ldone;
816
817        bool may_override = false;
818        for (size_t i = 0; i < cd->baseclasses->dim; i++)
819        {
820            BaseClass *b = (*cd->baseclasses)[i];
821            ClassDeclaration *cbd = b->type->toBasetype()->isClassHandle();
822            if (!cbd)
823                continue;
824            for (size_t j = 0; j < cbd->vtbl.dim; j++)
825            {
826                FuncDeclaration *f2 = cbd->vtbl[j]->isFuncDeclaration();
827                if (!f2 || f2->ident != ident)
828                    continue;
829                if (cbd->parent && cbd->parent->isTemplateInstance())
830                {
831                    if (!f2->functionSemantic())
832                        goto Ldone;
833                }
834                may_override = true;
835            }
836        }
837        if (may_override && type->nextOf() == NULL)
838        {
839            /* If same name function exists in base class but 'this' is auto return,
840             * cannot find index of base class's vtbl[] to override.
841             */
842            error("return type inference is not supported if may override base class function");
843        }
844
845        /* Find index of existing function in base class's vtbl[] to override
846         * (the index will be the same as in cd's current vtbl[])
847         */
848        int vi = cd->baseClass ? findVtblIndex((Dsymbols*)&cd->baseClass->vtbl, (int)cd->baseClass->vtbl.dim)
849                               : -1;
850
851        bool doesoverride = false;
852        switch (vi)
853        {
854            case -1:
855        Lintro:
856                /* Didn't find one, so
857                 * This is an 'introducing' function which gets a new
858                 * slot in the vtbl[].
859                 */
860
861                // Verify this doesn't override previous final function
862                if (cd->baseClass)
863                {
864                    Dsymbol *s = cd->baseClass->search(loc, ident);
865                    if (s)
866                    {
867                        FuncDeclaration *f2 = s->isFuncDeclaration();
868                        if (f2)
869                        {
870                            f2 = f2->overloadExactMatch(type);
871                            if (f2 && f2->isFinalFunc() && f2->prot().kind != PROTprivate)
872                                error("cannot override final function %s", f2->toPrettyChars());
873                        }
874                    }
875                }
876
877                /* These quirky conditions mimic what VC++ appears to do
878                 */
879                if (global.params.mscoff && cd->isCPPclass() &&
880                    cd->baseClass && cd->baseClass->vtbl.dim)
881                {
882                    /* if overriding an interface function, then this is not
883                     * introducing and don't put it in the class vtbl[]
884                     */
885                    interfaceVirtual = overrideInterface();
886                    if (interfaceVirtual)
887                    {
888                        //printf("\tinterface function %s\n", toChars());
889                        cd->vtblFinal.push(this);
890                        goto Linterfaces;
891                    }
892                }
893
894                if (isFinalFunc())
895                {
896                    // Don't check here, as it may override an interface function
897                    //if (isOverride())
898                        //error("is marked as override, but does not override any function");
899                    cd->vtblFinal.push(this);
900                }
901                else
902                {
903                    //printf("\tintroducing function %s\n", toChars());
904                    introducing = 1;
905                    if (cd->isCPPclass() && Target::reverseCppOverloads)
906                    {
907                        // with dmc, overloaded functions are grouped and in reverse order
908                        vtblIndex = (int)cd->vtbl.dim;
909                        for (int i = 0; i < (int)cd->vtbl.dim; i++)
910                        {
911                            if (cd->vtbl[i]->ident == ident && cd->vtbl[i]->parent == parent)
912                            {
913                                vtblIndex = (int)i;
914                                break;
915                            }
916                        }
917                        // shift all existing functions back
918                        for (int i = (int)cd->vtbl.dim; i > vtblIndex; i--)
919                        {
920                            FuncDeclaration *fd = cd->vtbl[i-1]->isFuncDeclaration();
921                            assert(fd);
922                            fd->vtblIndex++;
923                        }
924                        cd->vtbl.insert(vtblIndex, this);
925                    }
926                    else
927                    {
928                        // Append to end of vtbl[]
929                        vi = (int)cd->vtbl.dim;
930                        cd->vtbl.push(this);
931                        vtblIndex = vi;
932                    }
933                }
934                break;
935
936            case -2:
937                // can't determine because of forward references
938                errors = true;
939                return;
940
941            default:
942            {
943                FuncDeclaration *fdv = cd->baseClass->vtbl[vi]->isFuncDeclaration();
944                FuncDeclaration *fdc = cd->vtbl[vi]->isFuncDeclaration();
945                // This function is covariant with fdv
946
947                if (fdc == this)
948                {
949                    doesoverride = true;
950                    break;
951                }
952
953                if (fdc->toParent() == parent)
954                {
955                    //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
956                    //        vi, this, this->toChars(), this->type->toChars(), this->loc.toChars(),
957                    //            fdc,  fdc ->toChars(), fdc ->type->toChars(), fdc ->loc.toChars(),
958                    //            fdv,  fdv ->toChars(), fdv ->type->toChars(), fdv ->loc.toChars());
959
960                    // fdc overrides fdv exactly, then this introduces new function.
961                    if (fdc->type->mod == fdv->type->mod && this->type->mod != fdv->type->mod)
962                        goto Lintro;
963                }
964
965                // This function overrides fdv
966                if (fdv->isFinalFunc())
967                    error("cannot override final function %s", fdv->toPrettyChars());
968
969                if (!isOverride())
970                {
971                    if (fdv->isFuture())
972                    {
973                        ::deprecation(loc, "@future base class method %s is being overridden by %s; rename the latter",
974                            fdv->toPrettyChars(), toPrettyChars());
975                        // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
976                        goto Lintro;
977                    }
978                    else
979                    {
980                        int vi2 = findVtblIndex(&cd->baseClass->vtbl, (int)cd->baseClass->vtbl.dim, false);
981                        if (vi2 < 0)
982                            // https://issues.dlang.org/show_bug.cgi?id=17349
983                            ::deprecation(loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
984                                fdv->toPrettyChars(), toPrettyChars());
985                        else
986                            ::error(loc, "implicitly overriding base class method %s with %s deprecated; add 'override' attribute",
987                                fdv->toPrettyChars(), toPrettyChars());
988                    }
989                }
990
991                doesoverride = true;
992                if (fdc->toParent() == parent)
993                {
994                    // If both are mixins, or both are not, then error.
995                    // If either is not, the one that is not overrides the other.
996                    bool thismixin = this->parent->isClassDeclaration() != NULL;
997                    bool fdcmixin = fdc->parent->isClassDeclaration() != NULL;
998                    if (thismixin == fdcmixin)
999                    {
1000                        error("multiple overrides of same function");
1001                    }
1002                    else if (!thismixin)    // fdc overrides fdv
1003                    {
1004                        // this doesn't override any function
1005                        break;
1006                    }
1007                }
1008                cd->vtbl[vi] = this;
1009                vtblIndex = vi;
1010
1011                /* Remember which functions this overrides
1012                 */
1013                foverrides.push(fdv);
1014
1015                /* This works by whenever this function is called,
1016                 * it actually returns tintro, which gets dynamically
1017                 * cast to type. But we know that tintro is a base
1018                 * of type, so we could optimize it by not doing a
1019                 * dynamic cast, but just subtracting the isBaseOf()
1020                 * offset if the value is != null.
1021                 */
1022
1023                if (fdv->tintro)
1024                    tintro = fdv->tintro;
1025                else if (!type->equals(fdv->type))
1026                {
1027                    /* Only need to have a tintro if the vptr
1028                     * offsets differ
1029                     */
1030                    int offset;
1031                    if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
1032                    {
1033                        tintro = fdv->type;
1034                    }
1035                }
1036                break;
1037            }
1038        }
1039
1040        /* Go through all the interface bases.
1041         * If this function is covariant with any members of those interface
1042         * functions, set the tintro.
1043         */
1044    Linterfaces:
1045        for (size_t i = 0; i < cd->interfaces.length; i++)
1046        {
1047            BaseClass *b = cd->interfaces.ptr[i];
1048            vi = findVtblIndex((Dsymbols *)&b->sym->vtbl, (int)b->sym->vtbl.dim);
1049            switch (vi)
1050            {
1051                case -1:
1052                    break;
1053
1054                case -2:
1055                    // can't determine because of forward references
1056                    errors = true;
1057                    return;
1058
1059                default:
1060                {
1061                    FuncDeclaration *fdv = (FuncDeclaration *)b->sym->vtbl[vi];
1062                    Type *ti = NULL;
1063
1064                    /* Remember which functions this overrides
1065                     */
1066                    foverrides.push(fdv);
1067
1068                    /* Should we really require 'override' when implementing
1069                     * an interface function?
1070                     */
1071                    //if (!isOverride())
1072                        //warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
1073
1074                    if (fdv->tintro)
1075                        ti = fdv->tintro;
1076                    else if (!type->equals(fdv->type))
1077                    {
1078                        /* Only need to have a tintro if the vptr
1079                         * offsets differ
1080                         */
1081                        int offset;
1082                        if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
1083                        {
1084                            ti = fdv->type;
1085                        }
1086                    }
1087                    if (ti)
1088                    {
1089                        if (tintro)
1090                        {
1091                            if (!tintro->nextOf()->equals(ti->nextOf()) &&
1092                                !tintro->nextOf()->isBaseOf(ti->nextOf(), NULL) &&
1093                                !ti->nextOf()->isBaseOf(tintro->nextOf(), NULL))
1094                            {
1095                                error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
1096                            }
1097                        }
1098                        tintro = ti;
1099                    }
1100                    goto L2;
1101                }
1102            }
1103        }
1104
1105        if (!doesoverride && isOverride() && (type->nextOf() || !may_override))
1106        {
1107            BaseClass *bc = NULL;
1108            Dsymbol *s = NULL;
1109            for (size_t i = 0; i < cd->baseclasses->dim; i++)
1110            {
1111                bc = (*cd->baseclasses)[i];
1112                s = bc->sym->search_correct(ident);
1113                if (s) break;
1114            }
1115
1116            if (s)
1117                error("does not override any function, did you mean to override '%s%s'?",
1118                    bc->sym->isCPPclass() ? "extern (C++) " : "", s->toPrettyChars());
1119            else
1120                error("does not override any function");
1121        }
1122
1123    L2: ;
1124
1125        /* Go through all the interface bases.
1126         * Disallow overriding any final functions in the interface(s).
1127         */
1128        for (size_t i = 0; i < cd->interfaces.length; i++)
1129        {
1130            BaseClass *b = cd->interfaces.ptr[i];
1131            if (b->sym)
1132            {
1133                Dsymbol *s = search_function(b->sym, ident);
1134                if (s)
1135                {
1136                    FuncDeclaration *f2 = s->isFuncDeclaration();
1137                    if (f2)
1138                    {
1139                        f2 = f2->overloadExactMatch(type);
1140                        if (f2 && f2->isFinalFunc() && f2->prot().kind != PROTprivate)
1141                            error("cannot override final function %s.%s", b->sym->toChars(), f2->toPrettyChars());
1142                    }
1143                }
1144            }
1145        }
1146
1147        if (isOverride())
1148        {
1149            if (storage_class & STCdisable)
1150                deprecation("overridden functions cannot be annotated @disable");
1151            if (isDeprecated())
1152                deprecation("deprecated functions cannot be annotated @disable");
1153        }
1154    }
1155    else if (isOverride() && !parent->isTemplateInstance())
1156        error("override only applies to class member functions");
1157
1158    // Reflect this->type to f because it could be changed by findVtblIndex
1159    f = type->toTypeFunction();
1160
1161    /* Do not allow template instances to add virtual functions
1162     * to a class.
1163     */
1164    if (isVirtual())
1165    {
1166        TemplateInstance *ti = parent->isTemplateInstance();
1167        if (ti)
1168        {
1169            // Take care of nested templates
1170            while (1)
1171            {
1172                TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
1173                if (!ti2)
1174                    break;
1175                ti = ti2;
1176            }
1177
1178            // If it's a member template
1179            ClassDeclaration *cd = ti->tempdecl->isClassMember();
1180            if (cd)
1181            {
1182                error("cannot use template to add virtual function to class '%s'", cd->toChars());
1183            }
1184        }
1185    }
1186
1187    if (isMain())
1188        checkDmain();       // Check main() parameters and return type
1189
1190Ldone:
1191    /* Purity and safety can be inferred for some functions by examining
1192     * the function body.
1193     */
1194    if (canInferAttributes(this, sc))
1195        initInferAttributes(this);
1196
1197    Module::dprogress++;
1198    semanticRun = PASSsemanticdone;
1199
1200    /* Save scope for possible later use (if we need the
1201     * function internals)
1202     */
1203    _scope = sc->copy();
1204    _scope->setNoFree();
1205
1206    static bool printedMain = false;  // semantic might run more than once
1207    if (global.params.verbose && !printedMain)
1208    {
1209        const char *type = isMain() ? "main" : isWinMain() ? "winmain" : isDllMain() ? "dllmain" : (const char *)NULL;
1210        Module *mod = sc->_module;
1211
1212        if (type && mod)
1213        {
1214            printedMain = true;
1215            const char *name = mod->srcfile->toChars();
1216            const char *path = FileName::searchPath(global.path, name, true);
1217            message("entry     %-10s\t%s", type, path ? path : name);
1218        }
1219    }
1220
1221    if (fbody && isMain() && sc->_module->isRoot())
1222        Compiler::genCmain(sc);
1223
1224    assert(type->ty != Terror || errors);
1225}
1226
1227void FuncDeclaration::semantic2(Scope *sc)
1228{
1229    if (semanticRun >= PASSsemantic2done)
1230        return;
1231    assert(semanticRun <= PASSsemantic2);
1232    semanticRun = PASSsemantic2;
1233
1234    objc()->setSelector(this, sc);
1235    objc()->validateSelector(this);
1236
1237    if (parent->isClassDeclaration())
1238    {
1239        objc()->checkLinkage(this);
1240    }
1241}
1242
1243/****************************************************
1244 * Determine whether an 'out' contract is declared inside
1245 * the given function or any of its overrides.
1246 * Params:
1247 *      fd = the function to search
1248 * Returns:
1249 *      true    found an 'out' contract
1250 *      false   didn't find one
1251 */
1252static bool needsFensure(FuncDeclaration *fd)
1253{
1254    if (fd->fensure)
1255        return true;
1256
1257    for (size_t i = 0; i < fd->foverrides.dim; i++)
1258    {
1259        FuncDeclaration *fdv = fd->foverrides[i];
1260
1261        if (fdv->fensure)
1262            return true;
1263
1264        if (needsFensure(fdv))
1265            return true;
1266    }
1267    return false;
1268}
1269
1270/****************************************************
1271 * Rewrite contracts as nested functions, then call them. Doing it as nested
1272 * functions means that overriding functions can call them.
1273 * Params:
1274 *      fd = the function to rewrite contracts for
1275 */
1276static void buildEnsureRequire(FuncDeclaration *fdx)
1277{
1278    if (!fdx->isVirtual())
1279        return;
1280
1281    TypeFunction *f = (TypeFunction *)fdx->type;
1282
1283    if (fdx->frequire)
1284    {
1285        /*   in { ... }
1286         * becomes:
1287         *   void __require() { ... }
1288         *   __require();
1289         */
1290        Loc loc = fdx->frequire->loc;
1291        TypeFunction *tf = new TypeFunction(NULL, Type::tvoid, 0, LINKd);
1292        tf->isnothrow = f->isnothrow;
1293        tf->isnogc = f->isnogc;
1294        tf->purity = f->purity;
1295        tf->trust = f->trust;
1296        FuncDeclaration *fd = new FuncDeclaration(loc, loc,
1297                                                  Id::require, STCundefined, tf);
1298        fd->fbody = fdx->frequire;
1299        Statement *s1 = new ExpStatement(loc, fd);
1300        Expression *e = new CallExp(loc, new VarExp(loc, fd, false), (Expressions *)NULL);
1301        Statement *s2 = new ExpStatement(loc, e);
1302        fdx->frequire = new CompoundStatement(loc, s1, s2);
1303        fdx->fdrequire = fd;
1304    }
1305
1306    if (!fdx->outId && f->nextOf() && f->nextOf()->toBasetype()->ty != Tvoid)
1307        fdx->outId = Id::result; // provide a default
1308
1309    if (fdx->fensure)
1310    {
1311        /*   out (result) { ... }
1312         * becomes:
1313         *   void __ensure(ref tret result) { ... }
1314         *   __ensure(result);
1315         */
1316        Loc loc = fdx->fensure->loc;
1317        Parameters *fparams = new Parameters();
1318        Parameter *p = NULL;
1319        if (fdx->outId)
1320        {
1321            p = new Parameter(STCref | STCconst, f->nextOf(), fdx->outId, NULL);
1322            fparams->push(p);
1323        }
1324        TypeFunction *tf = new TypeFunction(fparams, Type::tvoid, 0, LINKd);
1325        tf->isnothrow = f->isnothrow;
1326        tf->isnogc = f->isnogc;
1327        tf->purity = f->purity;
1328        tf->trust = f->trust;
1329        FuncDeclaration *fd = new FuncDeclaration(loc, loc,
1330                                                  Id::ensure, STCundefined, tf);
1331        fd->fbody = fdx->fensure;
1332        Statement *s1 = new ExpStatement(loc, fd);
1333        Expression *eresult = NULL;
1334        if (fdx->outId)
1335            eresult = new IdentifierExp(loc, fdx->outId);
1336        Expression *e = new CallExp(loc, new VarExp(loc, fd, false), eresult);
1337        Statement *s2 = new ExpStatement(loc, e);
1338        fdx->fensure = new CompoundStatement(loc, s1, s2);
1339        fdx->fdensure = fd;
1340    }
1341}
1342
1343/* Determine if function should add `return 0;`
1344 */
1345static bool addReturn0(FuncDeclaration *funcdecl)
1346{
1347    TypeFunction *f = (TypeFunction *)funcdecl->type;
1348
1349    return f->next->ty == Tvoid &&
1350        (funcdecl->isMain() || (global.params.betterC && funcdecl->isCMain()));
1351}
1352
1353// Do the semantic analysis on the internals of the function.
1354
1355void FuncDeclaration::semantic3(Scope *sc)
1356{
1357    VarDeclaration *_arguments = NULL;
1358
1359    if (!parent)
1360    {
1361        if (global.errors)
1362            return;
1363        //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
1364        assert(0);
1365    }
1366    if (errors || isError(parent))
1367    {
1368        errors = true;
1369        return;
1370    }
1371    //printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", parent->toChars(), toChars(), this, sc, loc.toChars());
1372    //fflush(stdout);
1373    //printf("storage class = x%x %x\n", sc->stc, storage_class);
1374    //{ static int x; if (++x == 2) *(char*)0=0; }
1375    //printf("\tlinkage = %d\n", sc->linkage);
1376
1377    if (ident == Id::assign && !inuse)
1378    {
1379        if (storage_class & STCinference)
1380        {
1381            /* Bugzilla 15044: For generated opAssign function, any errors
1382             * from its body need to be gagged.
1383             */
1384            unsigned oldErrors = global.startGagging();
1385            ++inuse;
1386            semantic3(sc);
1387            --inuse;
1388            if (global.endGagging(oldErrors))   // if errors happened
1389            {
1390                // Disable generated opAssign, because some members forbid identity assignment.
1391                storage_class |= STCdisable;
1392                fbody = NULL;   // remove fbody which contains the error
1393                semantic3Errors = false;
1394            }
1395            return;
1396        }
1397    }
1398
1399    //printf(" sc->incontract = %d\n", (sc->flags & SCOPEcontract));
1400    if (semanticRun >= PASSsemantic3)
1401        return;
1402    semanticRun = PASSsemantic3;
1403    semantic3Errors = false;
1404
1405    if (!type || type->ty != Tfunction)
1406        return;
1407    TypeFunction *f = (TypeFunction *)type;
1408    if (!inferRetType && f->next->ty == Terror)
1409        return;
1410
1411    if (!fbody && inferRetType && !f->next)
1412    {
1413        error("has no function body with return type inference");
1414        return;
1415    }
1416
1417    unsigned oldErrors = global.errors;
1418
1419    if (frequire)
1420    {
1421        for (size_t i = 0; i < foverrides.dim; i++)
1422        {
1423            FuncDeclaration *fdv = foverrides[i];
1424
1425            if (fdv->fbody && !fdv->frequire)
1426            {
1427                error("cannot have an in contract when overriden function %s does not have an in contract", fdv->toPrettyChars());
1428                break;
1429            }
1430        }
1431    }
1432
1433    // Remember whether we need to generate an 'out' contract.
1434    bool needEnsure = needsFensure(this);
1435
1436    if (fbody || frequire || needEnsure)
1437    {
1438        /* Symbol table into which we place parameters and nested functions,
1439         * solely to diagnose name collisions.
1440         */
1441        localsymtab = new DsymbolTable();
1442
1443        // Establish function scope
1444        ScopeDsymbol *ss = new ScopeDsymbol();
1445        // find enclosing scope symbol, might skip symbol-less CTFE and/or FuncExp scopes
1446        for (Scope *scx = sc; ; scx = scx->enclosing)
1447        {
1448            if (scx->scopesym)
1449            {
1450                ss->parent = scx->scopesym;
1451                break;
1452            }
1453        }
1454        ss->loc = loc;
1455        ss->endlinnum = endloc.linnum;
1456        Scope *sc2 = sc->push(ss);
1457        sc2->func = this;
1458        sc2->parent = this;
1459        sc2->callSuper = 0;
1460        sc2->sbreak = NULL;
1461        sc2->scontinue = NULL;
1462        sc2->sw = NULL;
1463        sc2->fes = fes;
1464        sc2->linkage = LINKd;
1465        sc2->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCabstract |
1466                        STCdeprecated | STCoverride |
1467                        STC_TYPECTOR | STCfinal | STCtls | STCgshared | STCref | STCreturn |
1468                        STCproperty | STCnothrow | STCpure | STCsafe | STCtrusted | STCsystem);
1469        sc2->protection = Prot(PROTpublic);
1470        sc2->explicitProtection = 0;
1471        sc2->aligndecl = NULL;
1472        if (this->ident != Id::require && this->ident != Id::ensure)
1473            sc2->flags = sc->flags & ~SCOPEcontract;
1474        sc2->flags &= ~SCOPEcompile;
1475        sc2->tf = NULL;
1476        sc2->os = NULL;
1477        sc2->noctor = 0;
1478        sc2->userAttribDecl = NULL;
1479        if (sc2->intypeof == 1) sc2->intypeof = 2;
1480        sc2->fieldinit = NULL;
1481        sc2->fieldinit_dim = 0;
1482
1483        /* Note: When a lambda is defined immediately under aggregate member
1484         * scope, it should be contextless due to prevent interior pointers.
1485         * e.g.
1486         *      // dg points 'this' - it's interior pointer
1487         *      class C { int x; void delegate() dg = (){ this.x = 1; }; }
1488         *
1489         * However, lambdas could be used inside typeof, in order to check
1490         * some expressions varidity at compile time. For such case the lambda
1491         * body can access aggregate instance members.
1492         * e.g.
1493         *      class C { int x; static assert(is(typeof({ this.x = 1; }))); }
1494         *
1495         * To properly accept it, mark these lambdas as member functions.
1496         */
1497        if (FuncLiteralDeclaration *fld = isFuncLiteralDeclaration())
1498        {
1499            if (AggregateDeclaration *ad = isMember2())
1500            {
1501                if (!sc->intypeof)
1502                {
1503                    if (fld->tok == TOKdelegate)
1504                        error("cannot be %s members", ad->kind());
1505                    else
1506                        fld->tok = TOKfunction;
1507                }
1508                else
1509                {
1510                    if (fld->tok != TOKfunction)
1511                        fld->tok = TOKdelegate;
1512                }
1513            }
1514        }
1515
1516        // Declare 'this'
1517        AggregateDeclaration *ad = isThis();
1518        vthis = declareThis(sc2, ad);
1519        //printf("[%s] ad = %p vthis = %p\n", loc.toChars(), ad, vthis);
1520        //if (vthis) printf("\tvthis->type = %s\n", vthis->type->toChars());
1521
1522        // Declare hidden variable _arguments[] and _argptr
1523        if (f->varargs == 1)
1524        {
1525            if (f->linkage == LINKd)
1526            {
1527                // Variadic arguments depend on Typeinfo being defined
1528                if (!global.params.useTypeInfo || !Type::dtypeinfo || !Type::typeinfotypelist)
1529                {
1530                    if (!global.params.useTypeInfo)
1531                        error("D-style variadic functions cannot be used with -betterC");
1532                    else if (!Type::typeinfotypelist)
1533                        error("`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions");
1534                    else
1535                        error("`object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions");
1536                    fatal();
1537                }
1538
1539                // Declare _arguments[]
1540                v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
1541                v_arguments->storage_class |= STCtemp | STCparameter;
1542                v_arguments->semantic(sc2);
1543                sc2->insert(v_arguments);
1544                v_arguments->parent = this;
1545
1546                //Type *t = Type::typeinfo->type->constOf()->arrayOf();
1547                Type *t = Type::dtypeinfo->type->arrayOf();
1548                _arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL);
1549                _arguments->storage_class |= STCtemp;
1550                _arguments->semantic(sc2);
1551                sc2->insert(_arguments);
1552                _arguments->parent = this;
1553            }
1554            if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
1555            {
1556                // Declare _argptr
1557                Type *t = Type::tvalist;
1558                v_argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL);
1559                v_argptr->storage_class |= STCtemp;
1560                v_argptr->semantic(sc2);
1561                sc2->insert(v_argptr);
1562                v_argptr->parent = this;
1563            }
1564        }
1565
1566        /* Declare all the function parameters as variables
1567         * and install them in parameters[]
1568         */
1569        size_t nparams = Parameter::dim(f->parameters);
1570        if (nparams)
1571        {
1572            /* parameters[] has all the tuples removed, as the back end
1573             * doesn't know about tuples
1574             */
1575            parameters = new VarDeclarations();
1576            parameters->reserve(nparams);
1577            for (size_t i = 0; i < nparams; i++)
1578            {
1579                Parameter *fparam = Parameter::getNth(f->parameters, i);
1580                Identifier *id = fparam->ident;
1581                StorageClass stc = 0;
1582                if (!id)
1583                {
1584                    /* Generate identifier for un-named parameter,
1585                     * because we need it later on.
1586                     */
1587                    fparam->ident = id = Identifier::generateId("_param_", i);
1588                    stc |= STCtemp;
1589                }
1590                Type *vtype = fparam->type;
1591                VarDeclaration *v = new VarDeclaration(loc, vtype, id, NULL);
1592                //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
1593                stc |= STCparameter;
1594                if (f->varargs == 2 && i + 1 == nparams)
1595                    stc |= STCvariadic;
1596                if (flags & FUNCFLAGinferScope && !(fparam->storageClass & STCscope))
1597                    stc |= STCmaybescope;
1598                stc |= fparam->storageClass & (STCin | STCout | STCref | STCreturn | STCscope | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
1599                v->storage_class = stc;
1600                v->semantic(sc2);
1601                if (!sc2->insert(v))
1602                    error("parameter %s.%s is already defined", toChars(), v->toChars());
1603                else
1604                    parameters->push(v);
1605                localsymtab->insert(v);
1606                v->parent = this;
1607            }
1608        }
1609
1610        // Declare the tuple symbols and put them in the symbol table,
1611        // but not in parameters[].
1612        if (f->parameters)
1613        {
1614            for (size_t i = 0; i < f->parameters->dim; i++)
1615            {
1616                Parameter *fparam = (*f->parameters)[i];
1617
1618                if (!fparam->ident)
1619                    continue;                   // never used, so ignore
1620                if (fparam->type->ty == Ttuple)
1621                {
1622                    TypeTuple *t = (TypeTuple *)fparam->type;
1623                    size_t dim = Parameter::dim(t->arguments);
1624                    Objects *exps = new Objects();
1625                    exps->setDim(dim);
1626                    for (size_t j = 0; j < dim; j++)
1627                    {
1628                        Parameter *narg = Parameter::getNth(t->arguments, j);
1629                        assert(narg->ident);
1630                        VarDeclaration *v = sc2->search(Loc(), narg->ident, NULL)->isVarDeclaration();
1631                        assert(v);
1632                        Expression *e = new VarExp(v->loc, v);
1633                        (*exps)[j] = e;
1634                    }
1635                    assert(fparam->ident);
1636                    TupleDeclaration *v = new TupleDeclaration(loc, fparam->ident, exps);
1637                    //printf("declaring tuple %s\n", v->toChars());
1638                    v->isexp = true;
1639                    if (!sc2->insert(v))
1640                        error("parameter %s.%s is already defined", toChars(), v->toChars());
1641                    localsymtab->insert(v);
1642                    v->parent = this;
1643                }
1644            }
1645        }
1646
1647        // Precondition invariant
1648        Statement *fpreinv = NULL;
1649        if (addPreInvariant())
1650        {
1651            Expression *e = addInvariant(loc, sc, ad, vthis, isDtorDeclaration() != NULL);
1652            if (e)
1653                fpreinv = new ExpStatement(Loc(), e);
1654        }
1655
1656        // Postcondition invariant
1657        Statement *fpostinv = NULL;
1658        if (addPostInvariant())
1659        {
1660            Expression *e = addInvariant(loc, sc, ad, vthis, isCtorDeclaration() != NULL);
1661            if (e)
1662                fpostinv = new ExpStatement(Loc(), e);
1663        }
1664
1665        // Pre/Postcondition contract
1666        if (!fbody)
1667            buildEnsureRequire(this);
1668
1669        Scope *scout = NULL;
1670        if (needEnsure || addPostInvariant())
1671        {
1672            if ((needEnsure && global.params.useOut) || fpostinv)
1673            {
1674                returnLabel = new LabelDsymbol(Id::returnLabel);
1675            }
1676
1677            // scope of out contract (need for vresult->semantic)
1678            ScopeDsymbol *sym = new ScopeDsymbol();
1679            sym->parent = sc2->scopesym;
1680            sym->loc = loc;
1681            sym->endlinnum = endloc.linnum;
1682            scout = sc2->push(sym);
1683        }
1684
1685        if (fbody)
1686        {
1687            ScopeDsymbol *sym = new ScopeDsymbol();
1688            sym->parent = sc2->scopesym;
1689            sym->loc = loc;
1690            sym->endlinnum = endloc.linnum;
1691            sc2 = sc2->push(sym);
1692
1693            AggregateDeclaration *ad2 = isMember2();
1694
1695            /* If this is a class constructor
1696             */
1697            if (ad2 && isCtorDeclaration())
1698            {
1699                allocFieldinit(sc2, ad2->fields.dim);
1700                for (size_t i = 0; i < ad2->fields.dim; i++)
1701                {
1702                    VarDeclaration *v = ad2->fields[i];
1703                    v->ctorinit = 0;
1704                }
1705            }
1706
1707            if (!inferRetType && retStyle(f) != RETstack)
1708                nrvo_can = 0;
1709
1710            bool inferRef = (f->isref && (storage_class & STCauto));
1711
1712            fbody = ::semantic(fbody, sc2);
1713            if (!fbody)
1714                fbody = new CompoundStatement(Loc(), new Statements());
1715
1716            if (naked)
1717            {
1718                fpreinv = NULL;         // can't accommodate with no stack frame
1719                fpostinv = NULL;
1720            }
1721
1722            assert(type == f ||
1723                   (type->ty == Tfunction &&
1724                    f->purity == PUREimpure &&
1725                    ((TypeFunction *)type)->purity >= PUREfwdref));
1726            f = (TypeFunction *)type;
1727
1728            if (inferRetType)
1729            {
1730                // If no return type inferred yet, then infer a void
1731                if (!f->next)
1732                    f->next = Type::tvoid;
1733                if (f->checkRetType(loc))
1734                    fbody = new ErrorStatement();
1735            }
1736            if (global.params.vcomplex && f->next != NULL)
1737                f->next->checkComplexTransition(loc);
1738
1739            if (returns && !fbody->isErrorStatement())
1740            {
1741                for (size_t i = 0; i < returns->dim; )
1742                {
1743                    Expression *exp = (*returns)[i]->exp;
1744                    if (exp->op == TOKvar && ((VarExp *)exp)->var == vresult)
1745                    {
1746                        if (addReturn0(this))
1747                            exp->type = Type::tint32;
1748                        else
1749                            exp->type = f->next;
1750                        // Remove `return vresult;` from returns
1751                        returns->remove(i);
1752                        continue;
1753                    }
1754                    if (inferRef && f->isref && !exp->type->constConv(f->next))     // Bugzilla 13336
1755                        f->isref = false;
1756                    i++;
1757                }
1758            }
1759            if (f->isref)   // Function returns a reference
1760            {
1761                if (storage_class & STCauto)
1762                    storage_class &= ~STCauto;
1763            }
1764            if (retStyle(f) != RETstack)
1765                nrvo_can = 0;
1766
1767            if (fbody->isErrorStatement())
1768                ;
1769            else if (isStaticCtorDeclaration())
1770            {
1771                /* It's a static constructor. Ensure that all
1772                 * ctor consts were initialized.
1773                 */
1774                ScopeDsymbol *pd = toParent()->isScopeDsymbol();
1775                for (size_t i = 0; i < pd->members->dim; i++)
1776                {
1777                    Dsymbol *s = (*pd->members)[i];
1778                    s->checkCtorConstInit();
1779                }
1780            }
1781            else if (ad2 && isCtorDeclaration())
1782            {
1783                ClassDeclaration *cd = ad2->isClassDeclaration();
1784
1785                // Verify that all the ctorinit fields got initialized
1786                if (!(sc2->callSuper & CSXthis_ctor))
1787                {
1788                    for (size_t i = 0; i < ad2->fields.dim; i++)
1789                    {
1790                        VarDeclaration *v = ad2->fields[i];
1791                        if (v->isThisDeclaration())
1792                            continue;
1793                        if (v->ctorinit == 0)
1794                        {
1795                            /* Current bugs in the flow analysis:
1796                             * 1. union members should not produce error messages even if
1797                             *    not assigned to
1798                             * 2. structs should recognize delegating opAssign calls as well
1799                             *    as delegating calls to other constructors
1800                             */
1801                            if (v->isCtorinit() && !v->type->isMutable() && cd)
1802                                error("missing initializer for %s field %s", MODtoChars(v->type->mod), v->toChars());
1803                            else if (v->storage_class & STCnodefaultctor)
1804                                ::error(loc, "field %s must be initialized in constructor", v->toChars());
1805                            else if (v->type->needsNested())
1806                                ::error(loc, "field %s must be initialized in constructor, because it is nested struct", v->toChars());
1807                        }
1808                        else
1809                        {
1810                            bool mustInit = (v->storage_class & STCnodefaultctor ||
1811                                             v->type->needsNested());
1812                            if (mustInit && !(sc2->fieldinit[i] & CSXthis_ctor))
1813                            {
1814                                error("field %s must be initialized but skipped", v->toChars());
1815                            }
1816                        }
1817                    }
1818                }
1819                freeFieldinit(sc2);
1820
1821                if (cd &&
1822                    !(sc2->callSuper & CSXany_ctor) &&
1823                    cd->baseClass && cd->baseClass->ctor)
1824                {
1825                    sc2->callSuper = 0;
1826
1827                    // Insert implicit super() at start of fbody
1828                    FuncDeclaration *fd = resolveFuncCall(Loc(), sc2, cd->baseClass->ctor, NULL, vthis->type, NULL, 1);
1829                    if (!fd)
1830                    {
1831                        error("no match for implicit super() call in constructor");
1832                    }
1833                    else if (fd->storage_class & STCdisable)
1834                    {
1835                        error("cannot call super() implicitly because it is annotated with @disable");
1836                    }
1837                    else
1838                    {
1839                        Expression *e1 = new SuperExp(Loc());
1840                        Expression *e = new CallExp(Loc(), e1);
1841                        e = ::semantic(e, sc2);
1842
1843                        Statement *s = new ExpStatement(Loc(), e);
1844                        fbody = new CompoundStatement(Loc(), s, fbody);
1845                    }
1846                }
1847                //printf("callSuper = x%x\n", sc2->callSuper);
1848            }
1849
1850            /* https://issues.dlang.org/show_bug.cgi?id=17502
1851             * Wait until after the return type has been inferred before
1852             * generating the contracts for this function, and merging contracts
1853             * from overrides.
1854             *
1855             * https://issues.dlang.org/show_bug.cgi?id=17893
1856             * However should take care to generate this before inferered
1857             * function attributes are applied, such as 'nothrow'.
1858             *
1859             * This was originally at the end of the first semantic pass, but
1860             * required a fix-up to be done here for the '__result' variable
1861             * type of __ensure() inside auto functions, but this didn't work
1862             * if the out parameter was implicit.
1863             */
1864            buildEnsureRequire(this);
1865
1866            int blockexit = BEnone;
1867            if (!fbody->isErrorStatement())
1868            {
1869                // Check for errors related to 'nothrow'.
1870                unsigned int nothrowErrors = global.errors;
1871                blockexit = blockExit(fbody, this, f->isnothrow);
1872                if (f->isnothrow && (global.errors != nothrowErrors))
1873                    ::error(loc, "nothrow %s '%s' may throw", kind(), toPrettyChars());
1874                if (flags & FUNCFLAGnothrowInprocess)
1875                {
1876                    if (type == f) f = (TypeFunction *)f->copy();
1877                    f->isnothrow = !(blockexit & BEthrow);
1878                }
1879            }
1880
1881            if (fbody->isErrorStatement())
1882                ;
1883            else if (ad2 && isCtorDeclaration())
1884            {
1885                /* Append:
1886                 *  return this;
1887                 * to function body
1888                 */
1889                if (blockexit & BEfallthru)
1890                {
1891                    Statement *s = new ReturnStatement(loc, NULL);
1892                    s = ::semantic(s, sc2);
1893                    fbody = new CompoundStatement(loc, fbody, s);
1894                    hasReturnExp |= (hasReturnExp & 1 ? 16 : 1);
1895                }
1896            }
1897            else if (fes)
1898            {
1899                // For foreach(){} body, append a return 0;
1900                if (blockexit & BEfallthru)
1901                {
1902                    Expression *e = new IntegerExp(0);
1903                    Statement *s = new ReturnStatement(Loc(), e);
1904                    fbody = new CompoundStatement(Loc(), fbody, s);
1905                    hasReturnExp |= (hasReturnExp & 1 ? 16 : 1);
1906                }
1907                assert(!returnLabel);
1908            }
1909            else
1910            {
1911                const bool inlineAsm = (hasReturnExp & 8) != 0;
1912                if ((blockexit & BEfallthru) && f->next->ty != Tvoid && !inlineAsm)
1913                {
1914                    Expression *e;
1915                    if (!hasReturnExp)
1916                        error("has no return statement, but is expected to return a value of type %s", f->next->toChars());
1917                    else
1918                        error("no return exp; or assert(0); at end of function");
1919                    if (global.params.useAssert &&
1920                        !global.params.useInline)
1921                    {
1922                        /* Add an assert(0, msg); where the missing return
1923                         * should be.
1924                         */
1925                        e = new AssertExp(
1926                              endloc,
1927                              new IntegerExp(0),
1928                              new StringExp(loc, const_cast<char *>("missing return expression"))
1929                            );
1930                    }
1931                    else
1932                        e = new HaltExp(endloc);
1933                    e = new CommaExp(Loc(), e, f->next->defaultInit());
1934                    e = ::semantic(e, sc2);
1935                    Statement *s = new ExpStatement(Loc(), e);
1936                    fbody = new CompoundStatement(Loc(), fbody, s);
1937                }
1938            }
1939
1940            if (returns)
1941            {
1942                bool implicit0 = addReturn0(this);
1943                Type *tret = implicit0 ? Type::tint32 : f->next;
1944                assert(tret->ty != Tvoid);
1945                if (vresult || returnLabel)
1946                    buildResultVar(scout ? scout : sc2, tret);
1947
1948                /* Cannot move this loop into NrvoWalker, because
1949                 * returns[i] may be in the nested delegate for foreach-body.
1950                 */
1951                for (size_t i = 0; i < returns->dim; i++)
1952                {
1953                    ReturnStatement *rs = (*returns)[i];
1954                    Expression *exp = rs->exp;
1955                    if (exp->op == TOKerror)
1956                        continue;
1957                    if (tret->ty == Terror)
1958                    {
1959                        // Bugzilla 13702
1960                        exp = checkGC(sc2, exp);
1961                        continue;
1962                    }
1963
1964                    if (!exp->implicitConvTo(tret) &&
1965                        parametersIntersect(exp->type))
1966                    {
1967                        if (exp->type->immutableOf()->implicitConvTo(tret))
1968                            exp = exp->castTo(sc2, exp->type->immutableOf());
1969                        else if (exp->type->wildOf()->implicitConvTo(tret))
1970                            exp = exp->castTo(sc2, exp->type->wildOf());
1971                    }
1972                    exp = exp->implicitCastTo(sc2, tret);
1973
1974                    if (f->isref)
1975                    {
1976                        // Function returns a reference
1977                        exp = exp->toLvalue(sc2, exp);
1978                        checkReturnEscapeRef(sc2, exp, false);
1979                    }
1980                    else
1981                    {
1982                        exp = exp->optimize(WANTvalue);
1983
1984                        /* Bugzilla 10789:
1985                         * If NRVO is not possible, all returned lvalues should call their postblits.
1986                         */
1987                        if (!nrvo_can)
1988                            exp = doCopyOrMove(sc2, exp);
1989
1990                        if (tret->hasPointers())
1991                            checkReturnEscape(sc2, exp, false);
1992                    }
1993
1994                    exp = checkGC(sc2, exp);
1995
1996                    if (vresult)
1997                    {
1998                        // Create: return vresult = exp;
1999                        exp = new BlitExp(rs->loc, vresult, exp);
2000                        exp->type = vresult->type;
2001
2002                        if (rs->caseDim)
2003                            exp = Expression::combine(exp, new IntegerExp(rs->caseDim));
2004                    }
2005                    else if (tintro && !tret->equals(tintro->nextOf()))
2006                    {
2007                        exp = exp->implicitCastTo(sc2, tintro->nextOf());
2008                    }
2009                    rs->exp = exp;
2010                }
2011            }
2012            if (nrvo_var || returnLabel)
2013            {
2014                NrvoWalker nw;
2015                nw.fd = this;
2016                nw.sc = sc2;
2017                nw.visitStmt(fbody);
2018            }
2019
2020            sc2 = sc2->pop();
2021        }
2022
2023        frequire = mergeFrequire(frequire);
2024        fensure = mergeFensure(fensure, outId);
2025
2026        Statement *freq = frequire;
2027        Statement *fens = fensure;
2028
2029        /* Do the semantic analysis on the [in] preconditions and
2030         * [out] postconditions.
2031         */
2032        if (freq)
2033        {
2034            /* frequire is composed of the [in] contracts
2035             */
2036            ScopeDsymbol *sym = new ScopeDsymbol();
2037            sym->parent = sc2->scopesym;
2038            sym->loc = loc;
2039            sym->endlinnum = endloc.linnum;
2040            sc2 = sc2->push(sym);
2041            sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPErequire;
2042
2043            // BUG: need to error if accessing out parameters
2044            // BUG: need to treat parameters as const
2045            // BUG: need to disallow returns and throws
2046            // BUG: verify that all in and ref parameters are read
2047            freq = ::semantic(freq, sc2);
2048            blockExit(freq, this, false);
2049
2050            sc2 = sc2->pop();
2051
2052            if (!global.params.useIn)
2053                freq = NULL;
2054        }
2055
2056        if (fens)
2057        {
2058            /* fensure is composed of the [out] contracts
2059             */
2060            if (f->next->ty == Tvoid && outId)
2061                error("void functions have no result");
2062
2063            sc2 = scout;    //push
2064            sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPEensure;
2065
2066            // BUG: need to treat parameters as const
2067            // BUG: need to disallow returns and throws
2068            if (fensure && f->next->ty != Tvoid)
2069                buildResultVar(scout, f->next);
2070
2071            fens = ::semantic(fens, sc2);
2072            blockExit(fens, this, false);
2073
2074            sc2 = sc2->pop();
2075
2076            if (!global.params.useOut)
2077                fens = NULL;
2078        }
2079
2080        if (fbody && fbody->isErrorStatement())
2081            ;
2082        else
2083        {
2084            Statements *a = new Statements();
2085
2086            // Merge in initialization of 'out' parameters
2087            if (parameters)
2088            {
2089                for (size_t i = 0; i < parameters->dim; i++)
2090                {
2091                    VarDeclaration *v = (*parameters)[i];
2092                    if (v->storage_class & STCout)
2093                    {
2094                        assert(v->_init);
2095                        ExpInitializer *ie = v->_init->isExpInitializer();
2096                        assert(ie);
2097                        if (ie->exp->op == TOKconstruct)
2098                            ie->exp->op = TOKassign; // construction occured in parameter processing
2099                        a->push(new ExpStatement(Loc(), ie->exp));
2100                    }
2101                }
2102            }
2103
2104            if (v_argptr)
2105            {
2106                // Handled in FuncDeclaration::toObjFile
2107                v_argptr->_init = new VoidInitializer(loc);
2108            }
2109
2110            if (_arguments)
2111            {
2112                /* Advance to elements[] member of TypeInfo_Tuple with:
2113                 *  _arguments = v_arguments.elements;
2114                 */
2115                Expression *e = new VarExp(Loc(), v_arguments);
2116                e = new DotIdExp(Loc(), e, Id::elements);
2117                e = new ConstructExp(Loc(), _arguments, e);
2118                e = ::semantic(e, sc2);
2119
2120                _arguments->_init = new ExpInitializer(Loc(), e);
2121                DeclarationExp *de = new DeclarationExp(Loc(), _arguments);
2122                a->push(new ExpStatement(Loc(), de));
2123            }
2124
2125            // Merge contracts together with body into one compound statement
2126
2127            if (freq || fpreinv)
2128            {
2129                if (!freq)
2130                    freq = fpreinv;
2131                else if (fpreinv)
2132                    freq = new CompoundStatement(Loc(), freq, fpreinv);
2133
2134                a->push(freq);
2135            }
2136
2137            if (fbody)
2138                a->push(fbody);
2139
2140            if (fens || fpostinv)
2141            {
2142                if (!fens)
2143                    fens = fpostinv;
2144                else if (fpostinv)
2145                    fens = new CompoundStatement(Loc(), fpostinv, fens);
2146
2147                LabelStatement *ls = new LabelStatement(Loc(), Id::returnLabel, fens);
2148                returnLabel->statement = ls;
2149                a->push(returnLabel->statement);
2150
2151                if (f->next->ty != Tvoid && vresult)
2152                {
2153                    // Create: return vresult;
2154                    Expression *e = new VarExp(Loc(), vresult);
2155                    if (tintro)
2156                    {
2157                        e = e->implicitCastTo(sc, tintro->nextOf());
2158                        e = ::semantic(e, sc);
2159                    }
2160                    ReturnStatement *s = new ReturnStatement(Loc(), e);
2161                    a->push(s);
2162                }
2163            }
2164            if (addReturn0(this))
2165            {
2166                // Add a return 0; statement
2167                Statement *s = new ReturnStatement(Loc(), new IntegerExp(0));
2168                a->push(s);
2169            }
2170
2171            Statement *sbody = new CompoundStatement(Loc(), a);
2172            /* Append destructor calls for parameters as finally blocks.
2173             */
2174            if (parameters)
2175            {
2176                for (size_t i = 0; i < parameters->dim; i++)
2177                {
2178                    VarDeclaration *v = (*parameters)[i];
2179
2180                    if (v->storage_class & (STCref | STCout | STClazy))
2181                        continue;
2182
2183                    if (v->needsScopeDtor())
2184                    {
2185                        // same with ExpStatement.scopeCode()
2186                        Statement *s = new DtorExpStatement(Loc(), v->edtor, v);
2187                        v->storage_class |= STCnodtor;
2188
2189                        s = ::semantic(s, sc2);
2190
2191                        bool isnothrow = f->isnothrow & !(flags & FUNCFLAGnothrowInprocess);
2192                        int blockexit = blockExit(s, this, isnothrow);
2193                        if (f->isnothrow && isnothrow && blockexit & BEthrow)
2194                            ::error(loc, "nothrow %s '%s' may throw", kind(), toPrettyChars());
2195                        if (flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow)
2196                            f->isnothrow = false;
2197                        if (blockExit(sbody, this, f->isnothrow) == BEfallthru)
2198                            sbody = new CompoundStatement(Loc(), sbody, s);
2199                        else
2200                            sbody = new TryFinallyStatement(Loc(), sbody, s);
2201                    }
2202                }
2203            }
2204            // from this point on all possible 'throwers' are checked
2205            flags &= ~FUNCFLAGnothrowInprocess;
2206
2207            if (isSynchronized())
2208            {
2209                /* Wrap the entire function body in a synchronized statement
2210                 */
2211                ClassDeclaration *cd = isThis() ? isThis()->isClassDeclaration() : parent->isClassDeclaration();
2212
2213                if (cd)
2214                {
2215                    if (!global.params.is64bit &&
2216                        global.params.isWindows &&
2217                        !isStatic() && !sbody->usesEH() && !global.params.trace)
2218                    {
2219                        /* The back end uses the "jmonitor" hack for syncing;
2220                         * no need to do the sync at this level.
2221                         */
2222                    }
2223                    else
2224                    {
2225                        Expression *vsync;
2226                        if (isStatic())
2227                        {
2228                            // The monitor is in the ClassInfo
2229                            vsync = new DotIdExp(loc, resolve(loc, sc2, cd, false), Id::classinfo);
2230                        }
2231                        else
2232                        {
2233                            // 'this' is the monitor
2234                            vsync = new VarExp(loc, vthis);
2235                        }
2236                        sbody = new PeelStatement(sbody);       // don't redo semantic()
2237                        sbody = new SynchronizedStatement(loc, vsync, sbody);
2238                        sbody = ::semantic(sbody, sc2);
2239                    }
2240                }
2241                else
2242                {
2243                    error("synchronized function %s must be a member of a class", toChars());
2244                }
2245            }
2246
2247            // If declaration has no body, don't set sbody to prevent incorrect codegen.
2248            InterfaceDeclaration *id = parent->isInterfaceDeclaration();
2249            if (fbody || (id && (fdensure || fdrequire) && isVirtual()))
2250                fbody = sbody;
2251        }
2252
2253        // Fix up forward-referenced gotos
2254        if (gotos)
2255        {
2256            for (size_t i = 0; i < gotos->dim; ++i)
2257            {
2258                (*gotos)[i]->checkLabel();
2259            }
2260        }
2261
2262        if (naked && (fensure || frequire))
2263            error("naked assembly functions with contracts are not supported");
2264
2265        sc2->callSuper = 0;
2266        sc2->pop();
2267    }
2268
2269    if (checkClosure())
2270    {
2271        // We should be setting errors here instead of relying on the global error count.
2272        //errors = true;
2273    }
2274
2275    /* If function survived being marked as impure, then it is pure
2276     */
2277    if (flags & FUNCFLAGpurityInprocess)
2278    {
2279        flags &= ~FUNCFLAGpurityInprocess;
2280        if (type == f)
2281            f = (TypeFunction *)f->copy();
2282        f->purity = PUREfwdref;
2283    }
2284
2285    if (flags & FUNCFLAGsafetyInprocess)
2286    {
2287        flags &= ~FUNCFLAGsafetyInprocess;
2288        if (type == f)
2289            f = (TypeFunction *)f->copy();
2290        f->trust = TRUSTsafe;
2291    }
2292
2293    if (flags & FUNCFLAGnogcInprocess)
2294    {
2295        flags &= ~FUNCFLAGnogcInprocess;
2296        if (type == f)
2297            f = (TypeFunction *)f->copy();
2298        f->isnogc = true;
2299    }
2300
2301    if (flags & FUNCFLAGreturnInprocess)
2302    {
2303        flags &= ~FUNCFLAGreturnInprocess;
2304        if (storage_class & STCreturn)
2305        {
2306            if (type == f)
2307                f = (TypeFunction *)f->copy();
2308            f->isreturn = true;
2309        }
2310    }
2311
2312    flags &= ~FUNCFLAGinferScope;
2313
2314    // Infer STCscope
2315    if (parameters)
2316    {
2317        size_t nfparams = Parameter::dim(f->parameters);
2318        assert(nfparams == parameters->dim);
2319        for (size_t u = 0; u < parameters->dim; u++)
2320        {
2321            VarDeclaration *v = (*parameters)[u];
2322            if (v->storage_class & STCmaybescope)
2323            {
2324                //printf("Inferring scope for %s\n", v->toChars());
2325                Parameter *p = Parameter::getNth(f->parameters, u);
2326                v->storage_class &= ~STCmaybescope;
2327                v->storage_class |= STCscope | STCscopeinferred;
2328                p->storageClass |= STCscope | STCscopeinferred;
2329                assert(!(p->storageClass & STCmaybescope));
2330            }
2331        }
2332    }
2333
2334    if (vthis && vthis->storage_class & STCmaybescope)
2335    {
2336        vthis->storage_class &= ~STCmaybescope;
2337        vthis->storage_class |= STCscope | STCscopeinferred;
2338        f->isscope = true;
2339        f->isscopeinferred = true;
2340    }
2341
2342    // reset deco to apply inference result to mangled name
2343    if (f != type)
2344        f->deco = NULL;
2345
2346    // Do semantic type AFTER pure/nothrow inference.
2347    if (!f->deco && ident != Id::xopEquals && ident != Id::xopCmp)
2348    {
2349        sc = sc->push();
2350        if (isCtorDeclaration()) // Bugzilla #15665
2351            sc->flags |= SCOPEctor;
2352        sc->stc = 0;
2353        sc->linkage = linkage;  // Bugzilla 8496
2354        type = f->semantic(loc, sc);
2355        sc = sc->pop();
2356    }
2357
2358    /* If this function had instantiated with gagging, error reproduction will be
2359     * done by TemplateInstance::semantic.
2360     * Otherwise, error gagging should be temporarily ungagged by functionSemantic3.
2361     */
2362    semanticRun = PASSsemantic3done;
2363    semantic3Errors = (global.errors != oldErrors) || (fbody && fbody->isErrorStatement());
2364    if (type->ty == Terror)
2365        errors = true;
2366    //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
2367    //fflush(stdout);
2368}
2369
2370/****************************************************
2371 * Resolve forward reference of function signature -
2372 * parameter types, return type, and attributes.
2373 * Returns false if any errors exist in the signature.
2374 */
2375bool FuncDeclaration::functionSemantic()
2376{
2377    if (!_scope)
2378        return !errors;
2379
2380    if (!originalType)      // semantic not yet run
2381    {
2382        TemplateInstance *spec = isSpeculative();
2383        unsigned olderrs = global.errors;
2384        unsigned oldgag = global.gag;
2385        if (global.gag && !spec)
2386            global.gag = 0;
2387        semantic(_scope);
2388        global.gag = oldgag;
2389        if (spec && global.errors != olderrs)
2390            spec->errors = (global.errors - olderrs != 0);
2391        if (olderrs != global.errors)   // if errors compiling this function
2392            return false;
2393    }
2394
2395    // if inferring return type, sematic3 needs to be run
2396    // - When the function body contains any errors, we cannot assume
2397    //   the inferred return type is valid.
2398    //   So, the body errors should become the function signature error.
2399    if (inferRetType && type && !type->nextOf())
2400        return functionSemantic3();
2401
2402    TemplateInstance *ti;
2403    if (isInstantiated() && !isVirtualMethod() &&
2404        ((ti = parent->isTemplateInstance()) == NULL || ti->isTemplateMixin() || ti->tempdecl->ident == ident))
2405    {
2406        AggregateDeclaration *ad = isMember2();
2407        if (ad && ad->sizeok != SIZEOKdone)
2408        {
2409            /* Currently dmd cannot resolve forward references per methods,
2410             * then setting SIZOKfwd is too conservative and would break existing code.
2411             * So, just stop method attributes inference until ad->semantic() done.
2412             */
2413            //ad->sizeok = SIZEOKfwd;
2414        }
2415        else
2416            return functionSemantic3() || !errors;
2417    }
2418
2419    if (storage_class & STCinference)
2420        return functionSemantic3() || !errors;
2421
2422    return !errors;
2423}
2424
2425/****************************************************
2426 * Resolve forward reference of function body.
2427 * Returns false if any errors exist in the body.
2428 */
2429bool FuncDeclaration::functionSemantic3()
2430{
2431    if (semanticRun < PASSsemantic3 && _scope)
2432    {
2433        /* Forward reference - we need to run semantic3 on this function.
2434         * If errors are gagged, and it's not part of a template instance,
2435         * we need to temporarily ungag errors.
2436         */
2437        TemplateInstance *spec = isSpeculative();
2438        unsigned olderrs = global.errors;
2439        unsigned oldgag = global.gag;
2440        if (global.gag && !spec)
2441            global.gag = 0;
2442        semantic3(_scope);
2443        global.gag = oldgag;
2444
2445        // If it is a speculatively-instantiated template, and errors occur,
2446        // we need to mark the template as having errors.
2447        if (spec && global.errors != olderrs)
2448            spec->errors = (global.errors - olderrs != 0);
2449        if (olderrs != global.errors)   // if errors compiling this function
2450            return false;
2451    }
2452
2453    return !errors && !semantic3Errors;
2454}
2455
2456/****************************************************
2457 * Check that this function type is properly resolved.
2458 * If not, report "forward reference error" and return true.
2459 */
2460bool FuncDeclaration::checkForwardRef(Loc loc)
2461{
2462    if (!functionSemantic())
2463        return true;
2464
2465    /* No deco means the functionSemantic() call could not resolve
2466     * forward referenes in the type of this function.
2467     */
2468    if (!type->deco)
2469    {
2470        bool inSemantic3 = (inferRetType && semanticRun >= PASSsemantic3);
2471        ::error(loc, "forward reference to %s'%s'",
2472            (inSemantic3 ? "inferred return type of function " : ""),
2473            toChars());
2474        return true;
2475    }
2476    return false;
2477}
2478
2479VarDeclaration *FuncDeclaration::declareThis(Scope *sc, AggregateDeclaration *ad)
2480{
2481    if (ad)
2482    {
2483        VarDeclaration *v;
2484        {
2485            //printf("declareThis() %s\n", toChars());
2486            Type *thandle = ad->handleType();
2487            assert(thandle);
2488            thandle = thandle->addMod(type->mod);
2489            thandle = thandle->addStorageClass(storage_class);
2490            v = new ThisDeclaration(loc, thandle);
2491            v->storage_class |= STCparameter;
2492            if (thandle->ty == Tstruct)
2493            {
2494                v->storage_class |= STCref;
2495
2496                // if member function is marked 'inout', then 'this' is 'return ref'
2497                if (type->ty == Tfunction && ((TypeFunction *)type)->iswild & 2)
2498                    v->storage_class |= STCreturn;
2499            }
2500            if (type->ty == Tfunction)
2501            {
2502                TypeFunction *tf = (TypeFunction *)type;
2503                if (tf->isreturn)
2504                    v->storage_class |= STCreturn;
2505                if (tf->isscope)
2506                    v->storage_class |= STCscope;
2507            }
2508            if (flags & FUNCFLAGinferScope && !(v->storage_class & STCscope))
2509                v->storage_class |= STCmaybescope;
2510
2511            v->semantic(sc);
2512            if (!sc->insert(v))
2513                assert(0);
2514            v->parent = this;
2515            return v;
2516        }
2517    }
2518    else if (isNested())
2519    {
2520        /* The 'this' for a nested function is the link to the
2521         * enclosing function's stack frame.
2522         * Note that nested functions and member functions are disjoint.
2523         */
2524        VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo());
2525        v->storage_class |= STCparameter;
2526        if (type->ty == Tfunction)
2527        {
2528            TypeFunction *tf = (TypeFunction *)type;
2529            if (tf->isreturn)
2530                v->storage_class |= STCreturn;
2531            if (tf->isscope)
2532                v->storage_class |= STCscope;
2533        }
2534        if (flags & FUNCFLAGinferScope && !(v->storage_class & STCscope))
2535            v->storage_class |= STCmaybescope;
2536
2537        v->semantic(sc);
2538        if (!sc->insert(v))
2539            assert(0);
2540        v->parent = this;
2541        return v;
2542    }
2543
2544    return NULL;
2545}
2546
2547bool FuncDeclaration::equals(RootObject *o)
2548{
2549    if (this == o)
2550        return true;
2551
2552    Dsymbol *s = isDsymbol(o);
2553    if (s)
2554    {
2555        FuncDeclaration *fd1 = this;
2556        FuncDeclaration *fd2 = s->isFuncDeclaration();
2557        if (!fd2)
2558            return false;
2559
2560        FuncAliasDeclaration *fa1 = fd1->isFuncAliasDeclaration();
2561        FuncAliasDeclaration *fa2 = fd2->isFuncAliasDeclaration();
2562        if (fa1 && fa2)
2563        {
2564            return fa1->toAliasFunc()->equals(fa2->toAliasFunc()) &&
2565                   fa1->hasOverloads == fa2->hasOverloads;
2566        }
2567
2568        if (fa1 && (fd1 = fa1->toAliasFunc())->isUnique() && !fa1->hasOverloads)
2569            fa1 = NULL;
2570        if (fa2 && (fd2 = fa2->toAliasFunc())->isUnique() && !fa2->hasOverloads)
2571            fa2 = NULL;
2572        if ((fa1 != NULL) != (fa2 != NULL))
2573            return false;
2574
2575        return fd1->toParent()->equals(fd2->toParent()) &&
2576            fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type);
2577    }
2578    return false;
2579}
2580
2581/****************************************************
2582 * Declare result variable lazily.
2583 */
2584
2585void FuncDeclaration::buildResultVar(Scope *sc, Type *tret)
2586{
2587    if (!vresult)
2588    {
2589        Loc loc = fensure ? fensure->loc : this->loc;
2590
2591        /* If inferRetType is true, tret may not be a correct return type yet.
2592         * So, in here it may be a temporary type for vresult, and after
2593         * fbody->semantic() running, vresult->type might be modified.
2594         */
2595        vresult = new VarDeclaration(loc, tret, outId ? outId : Id::result, NULL);
2596        vresult->storage_class |= STCnodtor;
2597
2598        if (outId == Id::result)
2599            vresult->storage_class |= STCtemp;
2600        if (!isVirtual())
2601            vresult->storage_class |= STCconst;
2602        vresult->storage_class |= STCresult;
2603
2604        // set before the semantic() for checkNestedReference()
2605        vresult->parent = this;
2606    }
2607
2608    if (sc && vresult->semanticRun == PASSinit)
2609    {
2610        TypeFunction *tf = type->toTypeFunction();
2611        if (tf->isref)
2612            vresult->storage_class |= STCref;
2613        vresult->type = tret;
2614
2615        vresult->semantic(sc);
2616
2617        if (!sc->insert(vresult))
2618            error("out result %s is already defined", vresult->toChars());
2619        assert(vresult->parent == this);
2620    }
2621}
2622
2623/****************************************************
2624 * Merge into this function the 'in' contracts of all it overrides.
2625 * 'in's are OR'd together, i.e. only one of them needs to pass.
2626 */
2627
2628Statement *FuncDeclaration::mergeFrequire(Statement *sf)
2629{
2630    /* If a base function and its override both have an IN contract, then
2631     * only one of them needs to succeed. This is done by generating:
2632     *
2633     * void derived.in() {
2634     *  try {
2635     *    base.in();
2636     *  }
2637     *  catch () {
2638     *    ... body of derived.in() ...
2639     *  }
2640     * }
2641     *
2642     * So if base.in() doesn't throw, derived.in() need not be executed, and the contract is valid.
2643     * If base.in() throws, then derived.in()'s body is executed.
2644     */
2645
2646    /* Implementing this is done by having the overriding function call
2647     * nested functions (the fdrequire functions) nested inside the overridden
2648     * function. This requires that the stack layout of the calling function's
2649     * parameters and 'this' pointer be in the same place (as the nested
2650     * function refers to them).
2651     * This is easy for the parameters, as they are all on the stack in the same
2652     * place by definition, since it's an overriding function. The problem is
2653     * getting the 'this' pointer in the same place, since it is a local variable.
2654     * We did some hacks in the code generator to make this happen:
2655     *  1. always generate exception handler frame, or at least leave space for it
2656     *     in the frame (Windows 32 SEH only)
2657     *  2. always generate an EBP style frame
2658     *  3. since 'this' is passed in a register that is subsequently copied into
2659     *     a stack local, allocate that local immediately following the exception
2660     *     handler block, so it is always at the same offset from EBP.
2661     */
2662    for (size_t i = 0; i < foverrides.dim; i++)
2663    {
2664        FuncDeclaration *fdv = foverrides[i];
2665
2666        /* The semantic pass on the contracts of the overridden functions must
2667         * be completed before code generation occurs.
2668         * https://issues.dlang.org/show_bug.cgi?id=3602
2669         */
2670        if (fdv->frequire && fdv->semanticRun != PASSsemantic3done)
2671        {
2672            assert(fdv->_scope);
2673            Scope *sc = fdv->_scope->push();
2674            sc->stc &= ~STCoverride;
2675            fdv->semantic3(sc);
2676            sc->pop();
2677        }
2678
2679        sf = fdv->mergeFrequire(sf);
2680        if (sf && fdv->fdrequire)
2681        {
2682            //printf("fdv->frequire: %s\n", fdv->frequire->toChars());
2683            /* Make the call:
2684             *   try { __require(); }
2685             *   catch (Throwable) { frequire; }
2686             */
2687            Expression *eresult = NULL;
2688            Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdrequire, false), eresult);
2689            Statement *s2 = new ExpStatement(loc, e);
2690
2691            Catch *c = new Catch(loc, getThrowable(), NULL, sf);
2692            c->internalCatch = true;
2693            Catches *catches = new Catches();
2694            catches->push(c);
2695            sf = new TryCatchStatement(loc, s2, catches);
2696        }
2697        else
2698            return NULL;
2699    }
2700    return sf;
2701}
2702
2703/****************************************************
2704 * Merge into this function the 'out' contracts of all it overrides.
2705 * 'out's are AND'd together, i.e. all of them need to pass.
2706 */
2707
2708Statement *FuncDeclaration::mergeFensure(Statement *sf, Identifier *oid)
2709{
2710    /* Same comments as for mergeFrequire(), except that we take care
2711     * of generating a consistent reference to the 'result' local by
2712     * explicitly passing 'result' to the nested function as a reference
2713     * argument.
2714     * This won't work for the 'this' parameter as it would require changing
2715     * the semantic code for the nested function so that it looks on the parameter
2716     * list for the 'this' pointer, something that would need an unknown amount
2717     * of tweaking of various parts of the compiler that I'd rather leave alone.
2718     */
2719    for (size_t i = 0; i < foverrides.dim; i++)
2720    {
2721        FuncDeclaration *fdv = foverrides[i];
2722
2723        /* The semantic pass on the contracts of the overridden functions must
2724         * be completed before code generation occurs.
2725         * https://issues.dlang.org/show_bug.cgi?id=3602 and
2726         * https://issues.dlang.org/show_bug.cgi?id=5230
2727         */
2728        if (needsFensure(fdv) && fdv->semanticRun != PASSsemantic3done)
2729        {
2730            assert(fdv->_scope);
2731            Scope *sc = fdv->_scope->push();
2732            sc->stc &= ~STCoverride;
2733            fdv->semantic3(sc);
2734            sc->pop();
2735        }
2736
2737        sf = fdv->mergeFensure(sf, oid);
2738        if (fdv->fdensure)
2739        {
2740            //printf("fdv->fensure: %s\n", fdv->fensure->toChars());
2741            // Make the call: __ensure(result)
2742            Expression *eresult = NULL;
2743            if (outId)
2744            {
2745                eresult = new IdentifierExp(loc, oid);
2746
2747                Type *t1 = fdv->type->nextOf()->toBasetype();
2748                Type *t2 = this->type->nextOf()->toBasetype();
2749                if (t1->isBaseOf(t2, NULL))
2750                {
2751                    /* Making temporary reference variable is necessary
2752                     * in covariant return.
2753                     * See bugzilla 5204 and 10479.
2754                     */
2755                    ExpInitializer *ei = new ExpInitializer(Loc(), eresult);
2756                    VarDeclaration *v = new VarDeclaration(Loc(), t1, Identifier::generateId("__covres"), ei);
2757                    v->storage_class |= STCtemp;
2758                    DeclarationExp *de = new DeclarationExp(Loc(), v);
2759                    VarExp *ve = new VarExp(Loc(), v);
2760                    eresult = new CommaExp(Loc(), de, ve);
2761                }
2762            }
2763            Expression *e = new CallExp(loc, new VarExp(loc, fdv->fdensure, false), eresult);
2764            Statement *s2 = new ExpStatement(loc, e);
2765
2766            if (sf)
2767            {
2768                sf = new CompoundStatement(sf->loc, s2, sf);
2769            }
2770            else
2771                sf = s2;
2772        }
2773    }
2774    return sf;
2775}
2776
2777/****************************************************
2778 * Determine if 'this' overrides fd.
2779 * Return !=0 if it does.
2780 */
2781
2782int FuncDeclaration::overrides(FuncDeclaration *fd)
2783{   int result = 0;
2784
2785    if (fd->ident == ident)
2786    {
2787        int cov = type->covariant(fd->type);
2788        if (cov)
2789        {   ClassDeclaration *cd1 = toParent()->isClassDeclaration();
2790            ClassDeclaration *cd2 = fd->toParent()->isClassDeclaration();
2791
2792            if (cd1 && cd2 && cd2->isBaseOf(cd1, NULL))
2793                result = 1;
2794        }
2795    }
2796    return result;
2797}
2798
2799/*************************************************
2800 * Find index of function in vtbl[0..dim] that
2801 * this function overrides.
2802 * Prefer an exact match to a covariant one.
2803 * Params:
2804 *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
2805 * Returns:
2806 *      -1      didn't find one
2807 *      -2      can't determine because of forward references
2808 */
2809
2810int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349)
2811{
2812    //printf("findVtblIndex() %s\n", toChars());
2813    FuncDeclaration *mismatch = NULL;
2814    StorageClass mismatchstc = 0;
2815    int mismatchvi = -1;
2816    int exactvi = -1;
2817    int bestvi = -1;
2818    for (int vi = 0; vi < dim; vi++)
2819    {
2820        FuncDeclaration *fdv = (*vtbl)[vi]->isFuncDeclaration();
2821        if (fdv && fdv->ident == ident)
2822        {
2823            if (type->equals(fdv->type))        // if exact match
2824            {
2825                if (fdv->parent->isClassDeclaration())
2826                {
2827                    if (fdv->isFuture())
2828                    {
2829                        bestvi = vi;
2830                        continue;           // keep looking
2831                    }
2832                    return vi;                  // no need to look further
2833                }
2834
2835                if (exactvi >= 0)
2836                {
2837                    error("cannot determine overridden function");
2838                    return exactvi;
2839                }
2840                exactvi = vi;
2841
2842                bestvi = vi;
2843                continue;
2844            }
2845
2846            StorageClass stc = 0;
2847            int cov = type->covariant(fdv->type, &stc, fix17349);
2848            //printf("\tbaseclass cov = %d\n", cov);
2849            switch (cov)
2850            {
2851                case 0:         // types are distinct
2852                    break;
2853
2854                case 1:
2855                    bestvi = vi;        // covariant, but not identical
2856                    break;              // keep looking for an exact match
2857
2858                case 2:
2859                    mismatchvi = vi;
2860                    mismatchstc = stc;
2861                    mismatch = fdv;     // overrides, but is not covariant
2862                    break;              // keep looking for an exact match
2863
2864                case 3:
2865                    return -2;  // forward references
2866
2867                default:
2868                    assert(0);
2869            }
2870        }
2871    }
2872    if (bestvi == -1 && mismatch)
2873    {
2874        //type->print();
2875        //mismatch->type->print();
2876        //printf("%s %s\n", type->deco, mismatch->type->deco);
2877        //printf("stc = %llx\n", mismatchstc);
2878        if (mismatchstc)
2879        {   // Fix it by modifying the type to add the storage classes
2880            type = type->addStorageClass(mismatchstc);
2881            bestvi = mismatchvi;
2882        }
2883    }
2884    return bestvi;
2885}
2886
2887/*********************************
2888 * If function a function in a base class,
2889 * return that base class.
2890 * Params:
2891 *  cd = class that function is in
2892 * Returns:
2893 *  base class if overriding, NULL if not
2894 */
2895BaseClass *FuncDeclaration::overrideInterface()
2896{
2897    ClassDeclaration *cd = parent->isClassDeclaration();
2898    for (size_t i = 0; i < cd->interfaces.length; i++)
2899    {
2900        BaseClass *b = cd->interfaces.ptr[i];
2901        int v = findVtblIndex((Dsymbols *)&b->sym->vtbl, (int)b->sym->vtbl.dim);
2902        if (v >= 0)
2903            return b;
2904    }
2905    return NULL;
2906}
2907
2908/****************************************************
2909 * Overload this FuncDeclaration with the new one f.
2910 * Return true if successful; i.e. no conflict.
2911 */
2912
2913bool FuncDeclaration::overloadInsert(Dsymbol *s)
2914{
2915    //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s->toChars(), toChars());
2916    assert(s != this);
2917
2918    AliasDeclaration *ad = s->isAliasDeclaration();
2919    if (ad)
2920    {
2921        if (overnext)
2922            return overnext->overloadInsert(ad);
2923        if (!ad->aliassym && ad->type->ty != Tident && ad->type->ty != Tinstance)
2924        {
2925            //printf("\tad = '%s'\n", ad->type->toChars());
2926            return false;
2927        }
2928        overnext = ad;
2929        //printf("\ttrue: no conflict\n");
2930        return true;
2931    }
2932    TemplateDeclaration *td = s->isTemplateDeclaration();
2933    if (td)
2934    {
2935        if (!td->funcroot)
2936            td->funcroot = this;
2937        if (overnext)
2938            return overnext->overloadInsert(td);
2939        overnext = td;
2940        return true;
2941    }
2942    FuncDeclaration *fd = s->isFuncDeclaration();
2943    if (!fd)
2944        return false;
2945
2946    if (overnext)
2947    {
2948        td = overnext->isTemplateDeclaration();
2949        if (td)
2950            fd->overloadInsert(td);
2951        else
2952            return overnext->overloadInsert(fd);
2953    }
2954    overnext = fd;
2955    //printf("\ttrue: no conflict\n");
2956    return true;
2957}
2958
2959/***************************************************
2960 * Visit each overloaded function/template in turn, and call
2961 * (*fp)(param, s) on it.
2962 * Exit when no more, or (*fp)(param, f) returns nonzero.
2963 * Returns:
2964 *      ==0     continue
2965 *      !=0     done
2966 */
2967
2968int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *))
2969{
2970    Dsymbol *d;
2971    Dsymbol *next;
2972    for (d = fstart; d; d = next)
2973    {
2974        if (OverDeclaration *od = d->isOverDeclaration())
2975        {
2976            if (od->hasOverloads)
2977            {
2978                if (int r = overloadApply(od->aliassym, param, fp))
2979                    return r;
2980            }
2981            else
2982            {
2983                if (int r = (*fp)(param, od->aliassym))
2984                    return r;
2985            }
2986            next = od->overnext;
2987        }
2988        else if (FuncAliasDeclaration *fa = d->isFuncAliasDeclaration())
2989        {
2990            if (fa->hasOverloads)
2991            {
2992                if (int r = overloadApply(fa->funcalias, param, fp))
2993                    return r;
2994            }
2995            else
2996            {
2997                FuncDeclaration *fd = fa->toAliasFunc();
2998                if (!fd)
2999                {
3000                    d->error("is aliased to a function");
3001                    break;
3002                }
3003                if (int r = (*fp)(param, fd))
3004                    return r;
3005            }
3006            next = fa->overnext;
3007        }
3008        else if (AliasDeclaration *ad = d->isAliasDeclaration())
3009        {
3010            next = ad->toAlias();
3011            if (next == ad)
3012                break;
3013            if (next == fstart)
3014                break;
3015        }
3016        else if (TemplateDeclaration *td = d->isTemplateDeclaration())
3017        {
3018            if (int r = (*fp)(param, td))
3019                return r;
3020            next = td->overnext;
3021        }
3022        else
3023        {
3024            FuncDeclaration *fd = d->isFuncDeclaration();
3025            if (!fd)
3026            {
3027                d->error("is aliased to a function");
3028                break;              // BUG: should print error message?
3029            }
3030            if (int r = (*fp)(param, fd))
3031                return r;
3032            next = fd->overnext;
3033        }
3034    }
3035    return 0;
3036}
3037
3038/********************************************
3039 * If there are no overloads of function f, return that function,
3040 * otherwise return NULL.
3041 */
3042
3043FuncDeclaration *FuncDeclaration::isUnique()
3044{
3045  struct ParamUnique
3046  {
3047    static int fp(void *param, Dsymbol *s)
3048    {
3049        FuncDeclaration *f = s->isFuncDeclaration();
3050        if (!f)
3051            return 0;
3052        FuncDeclaration **pf = (FuncDeclaration **)param;
3053
3054        if (*pf)
3055        {
3056            *pf = NULL;
3057            return 1;               // ambiguous, done
3058        }
3059        else
3060        {
3061            *pf = f;
3062            return 0;
3063        }
3064    }
3065  };
3066    FuncDeclaration *result = NULL;
3067    overloadApply(this, &result, &ParamUnique::fp);
3068    return result;
3069}
3070
3071/********************************************
3072 * Find function in overload list that exactly matches t.
3073 */
3074
3075FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
3076{
3077  struct ParamExact
3078  {
3079    Type *t;            // type to match
3080    FuncDeclaration *f; // return value
3081
3082    static int fp(void *param, Dsymbol *s)
3083    {
3084        FuncDeclaration *f = s->isFuncDeclaration();
3085        if (!f)
3086            return 0;
3087        ParamExact *p = (ParamExact *)param;
3088        Type *t = p->t;
3089
3090        if (t->equals(f->type))
3091        {
3092            p->f = f;
3093            return 1;
3094        }
3095
3096        /* Allow covariant matches, as long as the return type
3097         * is just a const conversion.
3098         * This allows things like pure functions to match with an impure function type.
3099         */
3100        if (t->ty == Tfunction)
3101        {   TypeFunction *tf = (TypeFunction *)f->type;
3102            if (tf->covariant(t) == 1 &&
3103                tf->nextOf()->implicitConvTo(t->nextOf()) >= MATCHconst)
3104            {
3105                p->f = f;
3106                return 1;
3107            }
3108        }
3109        return 0;
3110    }
3111  };
3112    ParamExact p;
3113    p.t = t;
3114    p.f = NULL;
3115    overloadApply(this, &p, &ParamExact::fp);
3116    return p.f;
3117}
3118
3119void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod)
3120{
3121    bool bothMutable = ((lhsMod & rhsMod) == 0);
3122    bool sharedMismatch = ((lhsMod ^ rhsMod) & MODshared) != 0;
3123    bool sharedMismatchOnly = ((lhsMod ^ rhsMod) == MODshared);
3124
3125    if (lhsMod & MODshared)
3126        buf->writestring("shared ");
3127    else if (sharedMismatch && !(lhsMod & MODimmutable))
3128        buf->writestring("non-shared ");
3129
3130    if (bothMutable && sharedMismatchOnly)
3131    { }
3132    else if (lhsMod & MODimmutable)
3133        buf->writestring("immutable ");
3134    else if (lhsMod & MODconst)
3135        buf->writestring("const ");
3136    else if (lhsMod & MODwild)
3137        buf->writestring("inout ");
3138    else
3139        buf->writestring("mutable ");
3140}
3141
3142/********************************************
3143 * Find function in overload list that matches to the 'this' modifier.
3144 * There's four result types.
3145 *
3146 * 1. If the 'tthis' matches only one candidate, it's an "exact match".
3147 *    Returns the function and 'hasOverloads' is set to false.
3148 *      eg. If 'tthis" is mutable and there's only one mutable method.
3149 * 2. If there's two or more match candidates, but a candidate function will be
3150 *    a "better match".
3151 *    Returns the better match function but 'hasOverloads' is set to true.
3152 *      eg. If 'tthis' is mutable, and there's both mutable and const methods,
3153 *          the mutable method will be a better match.
3154 * 3. If there's two or more match candidates, but there's no better match,
3155 *    Returns NULL and 'hasOverloads' is set to true to represent "ambiguous match".
3156 *      eg. If 'tthis' is mutable, and there's two or more mutable methods.
3157 * 4. If there's no candidates, it's "no match" and returns NULL with error report.
3158 *      e.g. If 'tthis' is const but there's no const methods.
3159 */
3160FuncDeclaration *FuncDeclaration::overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads)
3161{
3162    //printf("FuncDeclaration::overloadModMatch('%s')\n", toChars());
3163    Match m;
3164    memset(&m, 0, sizeof(m));
3165    m.last = MATCHnomatch;
3166
3167  struct ParamMod
3168  {
3169    Match *m;
3170    Type *tthis;
3171
3172    static int fp(void *param, Dsymbol *s)
3173    {
3174        if (FuncDeclaration *fd = s->isFuncDeclaration())
3175            return ((ParamMod *)param)->fp(fd);
3176        return 0;
3177    }
3178    int fp(FuncDeclaration *f)
3179    {
3180        if (f == m->lastf)          // skip duplicates
3181            return 0;
3182
3183        m->anyf = f;
3184        TypeFunction *tf = f->type->toTypeFunction();
3185        //printf("tf = %s\n", tf->toChars());
3186
3187        MATCH match;
3188        if (tthis)   // non-static functions are preferred than static ones
3189        {
3190            if (f->needThis())
3191                match = f->isCtorDeclaration() ? MATCHexact : MODmethodConv(tthis->mod, tf->mod);
3192            else
3193                match = MATCHconst; // keep static funciton in overload candidates
3194        }
3195        else            // static functions are preferred than non-static ones
3196        {
3197            if (f->needThis())
3198                match = MATCHconvert;
3199            else
3200                match = MATCHexact;
3201        }
3202        if (match != MATCHnomatch)
3203        {
3204            if (match > m->last) goto LfIsBetter;
3205            if (match < m->last) goto LlastIsBetter;
3206
3207            /* See if one of the matches overrides the other.
3208             */
3209            if (m->lastf->overrides(f)) goto LlastIsBetter;
3210            if (f->overrides(m->lastf)) goto LfIsBetter;
3211
3212            //printf("\tambiguous\n");
3213            m->nextf = f;
3214            m->count++;
3215            return 0;
3216
3217        LlastIsBetter:
3218            //printf("\tlastbetter\n");
3219            m->count++; // count up
3220            return 0;
3221
3222        LfIsBetter:
3223            //printf("\tisbetter\n");
3224            if (m->last <= MATCHconvert)
3225            {
3226                // clear last secondary matching
3227                m->nextf = NULL;
3228                m->count = 0;
3229            }
3230            m->last = match;
3231            m->lastf = f;
3232            m->count++;     // count up
3233            return 0;
3234        }
3235        return 0;
3236    }
3237  };
3238    ParamMod p;
3239    p.m = &m;
3240    p.tthis = tthis;
3241    overloadApply(this, &p, &ParamMod::fp);
3242
3243    if (m.count == 1)       // exact match
3244    {
3245        hasOverloads = false;
3246    }
3247    else if (m.count > 1)   // better or ambiguous match
3248    {
3249        hasOverloads = true;
3250    }
3251    else                    // no match
3252    {
3253        hasOverloads = true;
3254        TypeFunction *tf = this->type->toTypeFunction();
3255        assert(tthis);
3256        assert(!MODimplicitConv(tthis->mod, tf->mod));  // modifier mismatch
3257        {
3258            OutBuffer thisBuf, funcBuf;
3259            MODMatchToBuffer(&thisBuf, tthis->mod, tf->mod);
3260            MODMatchToBuffer(&funcBuf, tf->mod, tthis->mod);
3261            ::error(loc, "%smethod %s is not callable using a %sobject",
3262                funcBuf.peekString(), this->toPrettyChars(), thisBuf.peekString());
3263        }
3264    }
3265
3266    return m.lastf;
3267}
3268
3269/********************************************
3270 * Returns true if function was declared
3271 * directly or indirectly in a unittest block
3272 */
3273bool FuncDeclaration::inUnittest()
3274{
3275    Dsymbol *f = this;
3276    do
3277    {
3278        if (f->isUnitTestDeclaration())
3279            return true;
3280        f = f->toParent();
3281    } while (f);
3282
3283    return false;
3284}
3285
3286/********************************************
3287 * find function template root in overload list
3288 */
3289
3290TemplateDeclaration *FuncDeclaration::findTemplateDeclRoot()
3291{
3292    FuncDeclaration *f = this;
3293    while (f && f->overnext)
3294    {
3295        //printf("f->overnext = %p %s\n", f->overnext, f->overnext->toChars());
3296        TemplateDeclaration *td = f->overnext->isTemplateDeclaration();
3297        if (td)
3298            return td;
3299        f = f->overnext->isFuncDeclaration();
3300    }
3301    return NULL;
3302}
3303
3304/*************************************
3305 * Determine partial specialization order of 'this' vs g.
3306 * This is very similar to TemplateDeclaration::leastAsSpecialized().
3307 * Returns:
3308 *      match   'this' is at least as specialized as g
3309 *      0       g is more specialized than 'this'
3310 */
3311
3312MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
3313{
3314    /* This works by calling g() with f()'s parameters, and
3315     * if that is possible, then f() is at least as specialized
3316     * as g() is.
3317     */
3318
3319    TypeFunction *tf = type->toTypeFunction();
3320    TypeFunction *tg = g->type->toTypeFunction();
3321    size_t nfparams = Parameter::dim(tf->parameters);
3322
3323    /* If both functions have a 'this' pointer, and the mods are not
3324     * the same and g's is not const, then this is less specialized.
3325     */
3326    if (needThis() && g->needThis() && tf->mod != tg->mod)
3327    {
3328        if (isCtorDeclaration())
3329        {
3330            if (!MODimplicitConv(tg->mod, tf->mod))
3331                return MATCHnomatch;
3332        }
3333        else
3334        {
3335            if (!MODimplicitConv(tf->mod, tg->mod))
3336                return MATCHnomatch;
3337        }
3338    }
3339
3340    /* Create a dummy array of arguments out of the parameters to f()
3341     */
3342    Expressions args;
3343    args.setDim(nfparams);
3344    for (size_t u = 0; u < nfparams; u++)
3345    {
3346        Parameter *p = Parameter::getNth(tf->parameters, u);
3347        Expression *e;
3348        if (p->storageClass & (STCref | STCout))
3349        {
3350            e = new IdentifierExp(Loc(), p->ident);
3351            e->type = p->type;
3352        }
3353        else
3354            e = p->type->defaultInitLiteral(Loc());
3355        args[u] = e;
3356    }
3357
3358    MATCH m = (MATCH) tg->callMatch(NULL, &args, 1);
3359    if (m > MATCHnomatch)
3360    {
3361        /* A variadic parameter list is less specialized than a
3362         * non-variadic one.
3363         */
3364        if (tf->varargs && !tg->varargs)
3365            goto L1;    // less specialized
3366
3367        return m;
3368    }
3369  L1:
3370    return MATCHnomatch;
3371}
3372
3373/// Walk through candidate template overloads and print them in the diagnostics.
3374struct TemplateCandidateWalker
3375{
3376    Loc loc;
3377    int numToDisplay;  // max num of overloads to print (-v overrides this).
3378
3379    /// Count template overloads.
3380    struct CountWalker
3381    {
3382        int numOverloads;
3383
3384        static int fp(void *param, Dsymbol *)
3385        {
3386            CountWalker *p = (CountWalker *)param;
3387            ++(p->numOverloads);
3388            return 0;
3389        }
3390    };
3391
3392    static int fp(void *param, Dsymbol *s)
3393    {
3394        TemplateDeclaration *t = s->isTemplateDeclaration();
3395        if (!t) return 0;
3396
3397        TemplateCandidateWalker *p = (TemplateCandidateWalker *)param;
3398
3399        ::errorSupplemental(t->loc, "%s", t->toPrettyChars());
3400
3401        if (!global.params.verbose && --(p->numToDisplay) == 0 && t->overnext)
3402        {
3403            // Too many overloads to sensibly display.
3404            // Just show count of remaining overloads.
3405            CountWalker cw;
3406            cw.numOverloads = 0;
3407            overloadApply(t->overnext, &cw, &CountWalker::fp);
3408
3409            if (cw.numOverloads > 0)
3410                ::errorSupplemental(p->loc, "... (%d more, -v to show) ...", cw.numOverloads);
3411
3412            return 1;  // stop iterating
3413        }
3414
3415        return 0;
3416    }
3417};
3418
3419/// Walk through candidate template overloads and print them in the diagnostics.
3420struct FuncCandidateWalker
3421{
3422    Loc loc;
3423    int numToDisplay;  // max num of overloads to print (-v overrides this).
3424
3425    /// Count function overloads.
3426    struct CountWalker
3427    {
3428        int numOverloads;
3429
3430        static int fp(void *param, Dsymbol *)
3431        {
3432            CountWalker *p = (CountWalker *)param;
3433            ++(p->numOverloads);
3434            return 0;
3435        }
3436    };
3437
3438    static int fp(void *param, Dsymbol *s)
3439    {
3440        FuncDeclaration *fd = s->isFuncDeclaration();
3441        TemplateDeclaration *td = s->isTemplateDeclaration();
3442        if (fd)
3443        {
3444            if (fd->errors || fd->type->ty == Terror)
3445                return 0;
3446
3447            TypeFunction *tf = (TypeFunction *)fd->type;
3448
3449            ::errorSupplemental(fd->loc, "%s%s", fd->toPrettyChars(),
3450                parametersTypeToChars(tf->parameters, tf->varargs));
3451        }
3452        else
3453        {
3454            ::errorSupplemental(td->loc, "%s", td->toPrettyChars());
3455        }
3456
3457        FuncCandidateWalker *p = (FuncCandidateWalker *)param;
3458        if (global.params.verbose || --(p->numToDisplay) != 0 || !fd)
3459            return 0;
3460
3461        // Too many overloads to sensibly display.
3462        CountWalker cw;
3463        cw.numOverloads = 0;
3464        overloadApply(fd->overnext, &cw, &CountWalker::fp);
3465
3466        if (cw.numOverloads > 0)
3467            ::errorSupplemental(p->loc, "... (%d more, -v to show) ...", cw.numOverloads);
3468
3469        return 1;  // stop iterating
3470    }
3471};
3472
3473/*******************************************
3474 * Given a symbol that could be either a FuncDeclaration or
3475 * a function template, resolve it to a function symbol.
3476 *      loc             instantiation location
3477 *      sc              instantiation scope
3478 *      tiargs          initial list of template arguments
3479 *      tthis           if !NULL, the 'this' pointer argument
3480 *      fargs           arguments to function
3481 *      flags           1: do not issue error message on no match, just return NULL
3482 *                      2: overloadResolve only
3483 */
3484
3485FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
3486        Objects *tiargs, Type *tthis, Expressions *fargs, int flags)
3487{
3488    if (!s)
3489        return NULL;                    // no match
3490
3491    if ((tiargs && arrayObjectIsError(tiargs)) ||
3492        (fargs  && arrayObjectIsError((Objects *)fargs)))
3493    {
3494        return NULL;
3495    }
3496
3497    Match m;
3498    memset(&m, 0, sizeof(m));
3499    m.last = MATCHnomatch;
3500
3501    functionResolve(&m, s, loc, sc, tiargs, tthis, fargs);
3502
3503    if (m.last > MATCHnomatch && m.lastf)
3504    {
3505        if (m.count == 1)   // exactly one match
3506        {
3507            if (!(flags & 1))
3508                m.lastf->functionSemantic();
3509            return m.lastf;
3510        }
3511        if ((flags & 2) && !tthis && m.lastf->needThis())
3512        {
3513            return m.lastf;
3514        }
3515    }
3516
3517    /* Failed to find a best match.
3518     * Do nothing or print error.
3519     */
3520    if (m.last <= MATCHnomatch)
3521    {
3522        // error was caused on matched function
3523        if (m.count == 1)
3524            return m.lastf;
3525
3526        // if do not print error messages
3527        if (flags & 1)
3528            return NULL;    // no match
3529    }
3530
3531    FuncDeclaration *fd = s->isFuncDeclaration();
3532    OverDeclaration *od = s->isOverDeclaration();
3533    TemplateDeclaration *td = s->isTemplateDeclaration();
3534    if (td && td->funcroot)
3535        s = fd = td->funcroot;
3536
3537    OutBuffer tiargsBuf;
3538    arrayObjectsToBuffer(&tiargsBuf, tiargs);
3539
3540    OutBuffer fargsBuf;
3541    fargsBuf.writeByte('(');
3542    argExpTypesToCBuffer(&fargsBuf, fargs);
3543    fargsBuf.writeByte(')');
3544    if (tthis)
3545        tthis->modToBuffer(&fargsBuf);
3546
3547    const int numOverloadsDisplay = 5; // sensible number to display
3548
3549    if (!m.lastf && !(flags & 1))   // no match
3550    {
3551        if (td && !fd)  // all of overloads are templates
3552        {
3553            ::error(loc, "%s %s.%s cannot deduce function from argument types !(%s)%s, candidates are:",
3554                    td->kind(), td->parent->toPrettyChars(), td->ident->toChars(),
3555                    tiargsBuf.peekString(), fargsBuf.peekString());
3556
3557            // Display candidate templates (even if there are no multiple overloads)
3558            TemplateCandidateWalker tcw;
3559            tcw.loc = loc;
3560            tcw.numToDisplay = numOverloadsDisplay;
3561            overloadApply(td, &tcw, &TemplateCandidateWalker::fp);
3562        }
3563        else if (od)
3564        {
3565            ::error(loc, "none of the overloads of '%s' are callable using argument types !(%s)%s",
3566                od->ident->toChars(), tiargsBuf.peekString(), fargsBuf.peekString());
3567        }
3568        else
3569        {
3570            assert(fd);
3571
3572            bool hasOverloads = fd->overnext != NULL;
3573            TypeFunction *tf = fd->type->toTypeFunction();
3574            if (tthis && !MODimplicitConv(tthis->mod, tf->mod)) // modifier mismatch
3575            {
3576                OutBuffer thisBuf, funcBuf;
3577                MODMatchToBuffer(&thisBuf, tthis->mod, tf->mod);
3578                MODMatchToBuffer(&funcBuf, tf->mod, tthis->mod);
3579                if (hasOverloads)
3580                    ::error(loc, "none of the overloads of '%s' are callable using a %sobject, candidates are:",
3581                        fd->ident->toChars(), thisBuf.peekString());
3582                else
3583                    ::error(loc, "%smethod %s is not callable using a %sobject",
3584                        funcBuf.peekString(), fd->toPrettyChars(), thisBuf.peekString());
3585            }
3586            else
3587            {
3588                //printf("tf = %s, args = %s\n", tf->deco, (*fargs)[0]->type->deco);
3589                if (hasOverloads)
3590                    ::error(loc, "none of the overloads of '%s' are callable using argument types %s, candidates are:",
3591                            fd->ident->toChars(), fargsBuf.peekString());
3592                else
3593                    fd->error(loc, "%s%s is not callable using argument types %s",
3594                        parametersTypeToChars(tf->parameters, tf->varargs),
3595                        tf->modToChars(),
3596                        fargsBuf.peekString());
3597            }
3598
3599            // Display candidate functions
3600            if (hasOverloads)
3601            {
3602                FuncCandidateWalker fcw;
3603                fcw.loc = loc;
3604                fcw.numToDisplay = numOverloadsDisplay;
3605                overloadApply(fd, &fcw, &FuncCandidateWalker::fp);
3606            }
3607        }
3608    }
3609    else if (m.nextf)
3610    {
3611        TypeFunction *tf1 = m.lastf->type->toTypeFunction();
3612        TypeFunction *tf2 = m.nextf->type->toTypeFunction();
3613        const char *lastprms = parametersTypeToChars(tf1->parameters, tf1->varargs);
3614        const char *nextprms = parametersTypeToChars(tf2->parameters, tf2->varargs);
3615        ::error(loc, "%s.%s called with argument types %s matches both:\n"
3616                     "%s:     %s%s\nand:\n%s:     %s%s",
3617                s->parent->toPrettyChars(), s->ident->toChars(),
3618                fargsBuf.peekString(),
3619                m.lastf->loc.toChars(), m.lastf->toPrettyChars(), lastprms,
3620                m.nextf->loc.toChars(), m.nextf->toPrettyChars(), nextprms);
3621    }
3622    return NULL;
3623}
3624
3625/********************************
3626 * Labels are in a separate scope, one per function.
3627 */
3628
3629LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
3630{   Dsymbol *s;
3631
3632    if (!labtab)
3633        labtab = new DsymbolTable();    // guess we need one
3634
3635    s = labtab->lookup(ident);
3636    if (!s)
3637    {
3638        s = new LabelDsymbol(ident);
3639        labtab->insert(s);
3640    }
3641    return (LabelDsymbol *)s;
3642}
3643
3644/*****************************************
3645 * Determine lexical level difference from 'this' to nested function 'fd'.
3646 * Error if this cannot call fd.
3647 * Returns:
3648 *      0       same level
3649 *      >0      decrease nesting by number
3650 *      -1      increase nesting by 1 (fd is nested within 'this')
3651 *      -2      error
3652 */
3653
3654int FuncDeclaration::getLevel(Loc loc, Scope *sc, FuncDeclaration *fd)
3655{
3656    int level;
3657    Dsymbol *s;
3658    Dsymbol *fdparent;
3659
3660    //printf("FuncDeclaration::getLevel(fd = '%s')\n", fd->toChars());
3661    fdparent = fd->toParent2();
3662    if (fdparent == this)
3663        return -1;
3664    s = this;
3665    level = 0;
3666    while (fd != s && fdparent != s->toParent2())
3667    {
3668        //printf("\ts = %s, '%s'\n", s->kind(), s->toChars());
3669        FuncDeclaration *thisfd = s->isFuncDeclaration();
3670        if (thisfd)
3671        {
3672            if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof)
3673                goto Lerr;
3674        }
3675        else
3676        {
3677            AggregateDeclaration *thiscd = s->isAggregateDeclaration();
3678            if (thiscd)
3679            {
3680                /* AggregateDeclaration::isNested returns true only when
3681                 * it has a hidden pointer.
3682                 * But, calling the function belongs unrelated lexical scope
3683                 * is still allowed inside typeof.
3684                 *
3685                 * struct Map(alias fun) {
3686                 *   typeof({ return fun(); }) RetType;
3687                 *   // No member function makes Map struct 'not nested'.
3688                 * }
3689                 */
3690                if (!thiscd->isNested() && !sc->intypeof)
3691                    goto Lerr;
3692            }
3693            else
3694                goto Lerr;
3695        }
3696
3697        s = s->toParent2();
3698        assert(s);
3699        level++;
3700    }
3701    return level;
3702
3703Lerr:
3704    // Don't give error if in template constraint
3705    if (!(sc->flags & SCOPEconstraint))
3706    {
3707        const char *xstatic = isStatic() ? "static " : "";
3708        // better diagnostics for static functions
3709        ::error(loc, "%s%s %s cannot access frame of function %s",
3710            xstatic, kind(), toPrettyChars(), fd->toPrettyChars());
3711        return -2;
3712    }
3713    return 1;
3714}
3715
3716const char *FuncDeclaration::toPrettyChars(bool QualifyTypes)
3717{
3718    if (isMain())
3719        return "D main";
3720    else
3721        return Dsymbol::toPrettyChars(QualifyTypes);
3722}
3723
3724/** for diagnostics, e.g. 'int foo(int x, int y) pure' */
3725const char *FuncDeclaration::toFullSignature()
3726{
3727    OutBuffer buf;
3728    functionToBufferWithIdent(type->toTypeFunction(), &buf, toChars());
3729    return buf.extractString();
3730}
3731
3732bool FuncDeclaration::isMain()
3733{
3734    return ident == Id::main &&
3735        linkage != LINKc && !isMember() && !isNested();
3736}
3737
3738bool FuncDeclaration::isCMain()
3739{
3740    return ident == Id::main &&
3741        linkage == LINKc && !isMember() && !isNested();
3742}
3743
3744bool FuncDeclaration::isWinMain()
3745{
3746    //printf("FuncDeclaration::isWinMain() %s\n", toChars());
3747    return ident == Id::WinMain &&
3748        linkage != LINKc && !isMember();
3749}
3750
3751bool FuncDeclaration::isDllMain()
3752{
3753    return ident == Id::DllMain &&
3754        linkage != LINKc && !isMember();
3755}
3756
3757bool FuncDeclaration::isExport() const
3758{
3759    return protection.kind == PROTexport;
3760}
3761
3762bool FuncDeclaration::isImportedSymbol() const
3763{
3764    //printf("isImportedSymbol()\n");
3765    //printf("protection = %d\n", protection);
3766    return (protection.kind == PROTexport) && !fbody;
3767}
3768
3769// Determine if function goes into virtual function pointer table
3770
3771bool FuncDeclaration::isVirtual()
3772{
3773    if (toAliasFunc() != this)
3774        return toAliasFunc()->isVirtual();
3775
3776    Dsymbol *p = toParent();
3777    return isMember() &&
3778        !(isStatic() || protection.kind == PROTprivate || protection.kind == PROTpackage) &&
3779        p->isClassDeclaration() &&
3780        !(p->isInterfaceDeclaration() && isFinalFunc());
3781}
3782
3783// Determine if a function is pedantically virtual
3784
3785bool FuncDeclaration::isVirtualMethod()
3786{
3787    if (toAliasFunc() != this)
3788        return toAliasFunc()->isVirtualMethod();
3789
3790    //printf("FuncDeclaration::isVirtualMethod() %s\n", toChars());
3791    if (!isVirtual())
3792        return false;
3793    // If it's a final method, and does not override anything, then it is not virtual
3794    if (isFinalFunc() && foverrides.dim == 0)
3795    {
3796        return false;
3797    }
3798    return true;
3799}
3800
3801bool FuncDeclaration::isFinalFunc()
3802{
3803    if (toAliasFunc() != this)
3804        return toAliasFunc()->isFinalFunc();
3805
3806    ClassDeclaration *cd;
3807    return isMember() &&
3808        (Declaration::isFinal() ||
3809         ((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal));
3810}
3811
3812bool FuncDeclaration::isCodeseg() const
3813{
3814    return true;                // functions are always in the code segment
3815}
3816
3817bool FuncDeclaration::isOverloadable()
3818{
3819    return true;                // functions can be overloaded
3820}
3821
3822PURE FuncDeclaration::isPure()
3823{
3824    //printf("FuncDeclaration::isPure() '%s'\n", toChars());
3825    TypeFunction *tf = type->toTypeFunction();
3826    if (flags & FUNCFLAGpurityInprocess)
3827        setImpure();
3828    if (tf->purity == PUREfwdref)
3829        tf->purityLevel();
3830    PURE purity = tf->purity;
3831    if (purity > PUREweak && isNested())
3832        purity = PUREweak;
3833    if (purity > PUREweak && needThis())
3834    {
3835        // The attribute of the 'this' reference affects purity strength
3836        if (type->mod & MODimmutable)
3837            ;
3838        else if (type->mod & (MODconst | MODwild) && purity >= PUREconst)
3839            purity = PUREconst;
3840        else
3841            purity = PUREweak;
3842    }
3843    tf->purity = purity;
3844    // ^ This rely on the current situation that every FuncDeclaration has a
3845    //   unique TypeFunction.
3846    return purity;
3847}
3848
3849PURE FuncDeclaration::isPureBypassingInference()
3850{
3851    if (flags & FUNCFLAGpurityInprocess)
3852        return PUREfwdref;
3853    else
3854        return isPure();
3855}
3856
3857/**************************************
3858 * The function is doing something impure,
3859 * so mark it as impure.
3860 * If there's a purity error, return true.
3861 */
3862bool FuncDeclaration::setImpure()
3863{
3864    if (flags & FUNCFLAGpurityInprocess)
3865    {
3866        flags &= ~FUNCFLAGpurityInprocess;
3867        if (fes)
3868            fes->func->setImpure();
3869    }
3870    else if (isPure())
3871        return true;
3872    return false;
3873}
3874
3875bool FuncDeclaration::isSafe()
3876{
3877    if (flags & FUNCFLAGsafetyInprocess)
3878        setUnsafe();
3879    return type->toTypeFunction()->trust == TRUSTsafe;
3880}
3881
3882bool FuncDeclaration::isSafeBypassingInference()
3883{
3884    return !(flags & FUNCFLAGsafetyInprocess) && isSafe();
3885}
3886
3887bool FuncDeclaration::isTrusted()
3888{
3889    if (flags & FUNCFLAGsafetyInprocess)
3890        setUnsafe();
3891    return type->toTypeFunction()->trust == TRUSTtrusted;
3892}
3893
3894/**************************************
3895 * The function is doing something unsave,
3896 * so mark it as unsafe.
3897 * If there's a safe error, return true.
3898 */
3899bool FuncDeclaration::setUnsafe()
3900{
3901    if (flags & FUNCFLAGsafetyInprocess)
3902    {
3903        flags &= ~FUNCFLAGsafetyInprocess;
3904        type->toTypeFunction()->trust = TRUSTsystem;
3905        if (fes)
3906            fes->func->setUnsafe();
3907    }
3908    else if (isSafe())
3909        return true;
3910    return false;
3911}
3912
3913bool FuncDeclaration::isNogc()
3914{
3915    if (flags & FUNCFLAGnogcInprocess)
3916        setGC();
3917    return type->toTypeFunction()->isnogc;
3918}
3919
3920bool FuncDeclaration::isNogcBypassingInference()
3921{
3922    return !(flags & FUNCFLAGnogcInprocess) && isNogc();
3923}
3924
3925/**************************************
3926 * The function is doing something that may allocate with the GC,
3927 * so mark it as not nogc (not no-how).
3928 * Returns:
3929 *      true if function is marked as @nogc, meaning a user error occurred
3930 */
3931bool FuncDeclaration::setGC()
3932{
3933    if (flags & FUNCFLAGnogcInprocess)
3934    {
3935        flags &= ~FUNCFLAGnogcInprocess;
3936        type->toTypeFunction()->isnogc = false;
3937        if (fes)
3938            fes->func->setGC();
3939    }
3940    else if (isNogc())
3941        return true;
3942    return false;
3943}
3944
3945/**************************************
3946 * Returns an indirect type one step from t.
3947 */
3948
3949Type *getIndirection(Type *t)
3950{
3951    t = t->baseElemOf();
3952    if (t->ty == Tarray || t->ty == Tpointer)
3953        return t->nextOf()->toBasetype();
3954    if (t->ty == Taarray || t->ty == Tclass)
3955        return t;
3956    if (t->ty == Tstruct)
3957        return t->hasPointers() ? t : NULL; // TODO
3958
3959    // should consider TypeDelegate?
3960    return NULL;
3961}
3962
3963/**************************************
3964 * Returns true if memory reachable through a reference B to a value of type tb,
3965 * which has been constructed with a reference A to a value of type ta
3966 * available, can alias memory reachable from A based on the types involved
3967 * (either directly or via any number of indirections).
3968 *
3969 * Note that this relation is not symmetric in the two arguments. For example,
3970 * a const(int) reference can point to a pre-existing int, but not the other
3971 * way round.
3972 */
3973bool traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool reversePass = false)
3974{
3975    Type *source = ta;
3976    Type *target = tb;
3977    if (reversePass)
3978    {
3979        source = tb;
3980        target = ta;
3981    }
3982
3983    if (source->constConv(target))
3984        return true;
3985    else if (target->ty == Tvoid && MODimplicitConv(source->mod, target->mod))
3986        return true;
3987
3988    // No direct match, so try breaking up one of the types (starting with tb).
3989    Type *tbb = tb->toBasetype()->baseElemOf();
3990    if (tbb != tb)
3991        return traverseIndirections(ta, tbb, p, reversePass);
3992
3993    // context date to detect circular look up
3994    struct Ctxt
3995    {
3996        Ctxt *prev;
3997        Type *type;
3998    };
3999    Ctxt *ctxt = (Ctxt *)p;
4000
4001    if (tb->ty == Tclass || tb->ty == Tstruct)
4002    {
4003        for (Ctxt *c = ctxt; c; c = c->prev)
4004            if (tb == c->type) return false;
4005        Ctxt c;
4006        c.prev = ctxt;
4007        c.type = tb;
4008
4009        AggregateDeclaration *sym = tb->toDsymbol(NULL)->isAggregateDeclaration();
4010        for (size_t i = 0; i < sym->fields.dim; i++)
4011        {
4012            VarDeclaration *v = sym->fields[i];
4013            Type *tprmi = v->type->addMod(tb->mod);
4014            //printf("\ttb = %s, tprmi = %s\n", tb->toChars(), tprmi->toChars());
4015            if (traverseIndirections(ta, tprmi, &c, reversePass))
4016                return true;
4017        }
4018    }
4019    else if (tb->ty == Tarray || tb->ty == Taarray || tb->ty == Tpointer)
4020    {
4021        Type *tind = tb->nextOf();
4022        if (traverseIndirections(ta, tind, ctxt, reversePass))
4023            return true;
4024    }
4025    else if (tb->hasPointers())
4026    {
4027        // FIXME: function pointer/delegate types should be considered.
4028        return true;
4029    }
4030
4031    // Still no match, so try breaking up ta if we have note done so yet.
4032    if (!reversePass)
4033        return traverseIndirections(tb, ta, ctxt, true);
4034
4035    return false;
4036}
4037
4038/********************************************
4039 * Returns true if the function return value has no indirection
4040 * which comes from the parameters.
4041 */
4042
4043bool FuncDeclaration::isolateReturn()
4044{
4045    TypeFunction *tf = type->toTypeFunction();
4046    assert(tf->next);
4047
4048    Type *treti = tf->next;
4049    treti = tf->isref ? treti : getIndirection(treti);
4050    if (!treti)
4051        return true;    // target has no mutable indirection
4052    return parametersIntersect(treti);
4053}
4054
4055/********************************************
4056 * Returns true if an object typed t can have indirections
4057 * which come from the parameters.
4058 */
4059
4060bool FuncDeclaration::parametersIntersect(Type *t)
4061{
4062    assert(t);
4063    if (!isPureBypassingInference() || isNested())
4064        return false;
4065
4066    TypeFunction *tf = type->toTypeFunction();
4067
4068    //printf("parametersIntersect(%s) t = %s\n", tf->toChars(), t->toChars());
4069
4070    size_t dim = Parameter::dim(tf->parameters);
4071    for (size_t i = 0; i < dim; i++)
4072    {
4073        Parameter *fparam = Parameter::getNth(tf->parameters, i);
4074        if (!fparam->type)
4075            continue;
4076        Type *tprmi = (fparam->storageClass & (STClazy | STCout | STCref))
4077                ? fparam->type : getIndirection(fparam->type);
4078        if (!tprmi)
4079            continue;   // there is no mutable indirection
4080
4081        //printf("\t[%d] tprmi = %d %s\n", i, tprmi->ty, tprmi->toChars());
4082        if (traverseIndirections(tprmi, t))
4083            return false;
4084    }
4085    if (AggregateDeclaration *ad = isCtorDeclaration() ? NULL : isThis())
4086    {
4087        Type *tthis = ad->getType()->addMod(tf->mod);
4088        //printf("\ttthis = %s\n", tthis->toChars());
4089        if (traverseIndirections(tthis, t))
4090            return false;
4091    }
4092
4093    return true;
4094}
4095
4096/****************************************
4097 * Determine if function needs a static frame pointer.
4098 * Returns:
4099 *  `true` if function is really nested within other function.
4100 * Contracts:
4101 *  If isNested() returns true, isThis() should return false.
4102 */
4103bool FuncDeclaration::isNested()
4104{
4105    FuncDeclaration *f = toAliasFunc();
4106    //printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
4107    return ((f->storage_class & STCstatic) == 0) &&
4108           (f->linkage == LINKd) &&
4109           (f->toParent2()->isFuncDeclaration() != NULL);
4110}
4111
4112/****************************************
4113 * Determine if function is a non-static member function
4114 * that has an implicit 'this' expression.
4115 * Returns:
4116 *  The aggregate it is a member of, or null.
4117 * Contracts:
4118 *  If isThis() returns true, isNested() should return false.
4119 */
4120AggregateDeclaration *FuncDeclaration::isThis()
4121{
4122    //printf("+FuncDeclaration::isThis() '%s'\n", toChars());
4123    AggregateDeclaration *ad = (storage_class & STCstatic) ? NULL : isMember2();
4124    //printf("-FuncDeclaration::isThis() %p\n", ad);
4125    return ad;
4126}
4127
4128bool FuncDeclaration::needThis()
4129{
4130    //printf("FuncDeclaration::needThis() '%s'\n", toChars());
4131    return toAliasFunc()->isThis() != NULL;
4132}
4133
4134bool FuncDeclaration::addPreInvariant()
4135{
4136    AggregateDeclaration *ad = isThis();
4137    ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
4138    return (ad && !(cd && cd->isCPPclass()) &&
4139            global.params.useInvariants &&
4140            (protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
4141            !naked);
4142}
4143
4144bool FuncDeclaration::addPostInvariant()
4145{
4146    AggregateDeclaration *ad = isThis();
4147    ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
4148    return (ad && !(cd && cd->isCPPclass()) &&
4149            ad->inv &&
4150            global.params.useInvariants &&
4151            (protection.kind == PROTprotected || protection.kind == PROTpublic || protection.kind == PROTexport) &&
4152            !naked);
4153}
4154
4155/********************************************************
4156 * Generate Expression to call the invariant.
4157 * Input:
4158 *      ad      aggregate with the invariant
4159 *      vthis   variable with 'this'
4160 *      direct  call invariant directly
4161 * Returns:
4162 *      void expression that calls the invariant
4163 */
4164Expression *addInvariant(Loc loc, Scope *sc, AggregateDeclaration *ad, VarDeclaration *vthis, bool direct)
4165{
4166    Expression *e = NULL;
4167    if (direct)
4168    {
4169        // Call invariant directly only if it exists
4170        FuncDeclaration *inv = ad->inv;
4171        ClassDeclaration *cd = ad->isClassDeclaration();
4172
4173        while (!inv && cd)
4174        {
4175            cd = cd->baseClass;
4176            if (!cd)
4177                break;
4178            inv = cd->inv;
4179        }
4180        if (inv)
4181        {
4182        #if 1
4183            // Workaround for bugzilla 13394: For the correct mangling,
4184            // run attribute inference on inv if needed.
4185            inv->functionSemantic();
4186        #endif
4187
4188            //e = new DsymbolExp(Loc(), inv);
4189            //e = new CallExp(Loc(), e);
4190            //e = e->semantic(sc2);
4191
4192            /* Bugzilla 13113: Currently virtual invariant calls completely
4193             * bypass attribute enforcement.
4194             * Change the behavior of pre-invariant call by following it.
4195             */
4196            e = new ThisExp(Loc());
4197            e->type = vthis->type;
4198            e = new DotVarExp(Loc(), e, inv, false);
4199            e->type = inv->type;
4200            e = new CallExp(Loc(), e);
4201            e->type = Type::tvoid;
4202        }
4203    }
4204    else
4205    {
4206    #if 1
4207        // Workaround for bugzilla 13394: For the correct mangling,
4208        // run attribute inference on inv if needed.
4209        if (ad->isStructDeclaration() && ad->inv)
4210            ad->inv->functionSemantic();
4211    #endif
4212
4213        // Call invariant virtually
4214        Expression *v = new ThisExp(Loc());
4215        v->type = vthis->type;
4216        if (ad->isStructDeclaration())
4217            v = v->addressOf();
4218        e = new StringExp(Loc(), const_cast<char *>("null this"));
4219        e = new AssertExp(loc, v, e);
4220        e = semantic(e, sc);
4221    }
4222    return e;
4223}
4224
4225/**********************************
4226 * Generate a FuncDeclaration for a runtime library function.
4227 */
4228
4229FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, const char *name, StorageClass stc)
4230{
4231    return genCfunc(fparams, treturn, Identifier::idPool(name), stc);
4232}
4233
4234FuncDeclaration *FuncDeclaration::genCfunc(Parameters *fparams, Type *treturn, Identifier *id, StorageClass stc)
4235{
4236    FuncDeclaration *fd;
4237    TypeFunction *tf;
4238    Dsymbol *s;
4239    static DsymbolTable *st = NULL;
4240
4241    //printf("genCfunc(name = '%s')\n", id->toChars());
4242    //printf("treturn\n\t"); treturn->print();
4243
4244    // See if already in table
4245    if (!st)
4246        st = new DsymbolTable();
4247    s = st->lookup(id);
4248    if (s)
4249    {
4250        fd = s->isFuncDeclaration();
4251        assert(fd);
4252        assert(fd->type->nextOf()->equals(treturn));
4253    }
4254    else
4255    {
4256        tf = new TypeFunction(fparams, treturn, 0, LINKc, stc);
4257        fd = new FuncDeclaration(Loc(), Loc(), id, STCstatic, tf);
4258        fd->protection = Prot(PROTpublic);
4259        fd->linkage = LINKc;
4260
4261        st->insert(fd);
4262    }
4263    return fd;
4264}
4265
4266/******************
4267 * Check parameters and return type of D main() function.
4268 * Issue error messages.
4269 */
4270void FuncDeclaration::checkDmain()
4271{
4272    TypeFunction *tf = type->toTypeFunction();
4273    const size_t nparams = Parameter::dim(tf->parameters);
4274    bool argerr = false;
4275    if (nparams == 1)
4276    {
4277        Parameter *fparam0 = Parameter::getNth(tf->parameters, 0);
4278        Type *t = fparam0->type->toBasetype();
4279        if (t->ty != Tarray ||
4280            t->nextOf()->ty != Tarray ||
4281            t->nextOf()->nextOf()->ty != Tchar ||
4282            fparam0->storageClass & (STCout | STCref | STClazy))
4283        {
4284            argerr = true;
4285        }
4286    }
4287
4288    if (!tf->nextOf())
4289        error("must return int or void");
4290    else if (tf->nextOf()->ty != Tint32 && tf->nextOf()->ty != Tvoid)
4291        error("must return int or void, not %s", tf->nextOf()->toChars());
4292    else if (tf->varargs || nparams >= 2 || argerr)
4293        error("parameters must be main() or main(string[] args)");
4294}
4295
4296const char *FuncDeclaration::kind() const
4297{
4298    return generated ? "generated function" : "function";
4299}
4300
4301/*********************************************
4302 * In the current function, we are calling 'this' function.
4303 * 1. Check to see if the current function can call 'this' function, issue error if not.
4304 * 2. If the current function is not the parent of 'this' function, then add
4305 *    the current function to the list of siblings of 'this' function.
4306 * 3. If the current function is a literal, and it's accessing an uplevel scope,
4307 *    then mark it as a delegate.
4308 * Returns true if error occurs.
4309 */
4310bool FuncDeclaration::checkNestedReference(Scope *sc, Loc loc)
4311{
4312    //printf("FuncDeclaration::checkNestedReference() %s\n", toPrettyChars());
4313
4314    if (FuncLiteralDeclaration *fld = this->isFuncLiteralDeclaration())
4315    {
4316        if (fld->tok == TOKreserved)
4317        {
4318            fld->tok = TOKfunction;
4319            fld->vthis = NULL;
4320        }
4321    }
4322
4323    if (!parent || parent == sc->parent)
4324        return false;
4325    if (ident == Id::require || ident == Id::ensure)
4326        return false;
4327    if (!isThis() && !isNested())
4328        return false;
4329
4330    // The current function
4331    FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
4332    if (!fdthis)
4333        return false;   // out of function scope
4334
4335    Dsymbol *p = toParent2();
4336
4337    // Function literals from fdthis to p must be delegates
4338    checkNestedRef(fdthis, p);
4339
4340    if (isNested())
4341    {
4342        // The function that this function is in
4343        FuncDeclaration *fdv = p->isFuncDeclaration();
4344        if (!fdv)
4345            return false;
4346        if (fdv == fdthis)
4347            return false;
4348
4349        //printf("this = %s in [%s]\n", this->toChars(), this->loc.toChars());
4350        //printf("fdv = %s in [%s]\n", fdv->toChars(), fdv->loc.toChars());
4351        //printf("fdthis = %s in [%s]\n", fdthis->toChars(), fdthis->loc.toChars());
4352
4353        // Add this function to the list of those which called us
4354        if (fdthis != this)
4355        {
4356            bool found = false;
4357            for (size_t i = 0; i < siblingCallers.dim; ++i)
4358            {
4359                if (siblingCallers[i] == fdthis)
4360                    found = true;
4361            }
4362            if (!found)
4363            {
4364                //printf("\tadding sibling %s\n", fdthis->toPrettyChars());
4365                if (!sc->intypeof && !(sc->flags & SCOPEcompile))
4366                    siblingCallers.push(fdthis);
4367            }
4368        }
4369
4370        int lv = fdthis->getLevel(loc, sc, fdv);
4371        if (lv == -2)
4372            return true;    // error
4373        if (lv == -1)
4374            return false;   // downlevel call
4375        if (lv == 0)
4376            return false;   // same level call
4377        // Uplevel call
4378    }
4379    return false;
4380}
4381
4382/* For all functions between outerFunc and f, mark them as needing
4383 * a closure.
4384 */
4385void markAsNeedingClosure(Dsymbol *f, FuncDeclaration *outerFunc)
4386{
4387    for (Dsymbol *sx = f; sx && sx != outerFunc; sx = sx->parent)
4388    {
4389        FuncDeclaration *fy = sx->isFuncDeclaration();
4390        if (fy && fy->closureVars.dim)
4391        {
4392            /* fy needs a closure if it has closureVars[],
4393             * because the frame pointer in the closure will be accessed.
4394             */
4395            fy->requiresClosure = true;
4396        }
4397    }
4398}
4399
4400
4401/* Given a nested function f inside a function outerFunc, check
4402 * if any sibling callers of f have escaped. If so, mark
4403 * all the enclosing functions as needing closures.
4404 * Return true if any closures were detected.
4405 * This is recursive: we need to check the callers of our siblings.
4406 * Note that nested functions can only call lexically earlier nested
4407 * functions, so loops are impossible.
4408 */
4409bool checkEscapingSiblings(FuncDeclaration *f, FuncDeclaration *outerFunc, void *p = NULL)
4410{
4411    struct PrevSibling
4412    {
4413        PrevSibling *p;
4414        FuncDeclaration *f;
4415    };
4416
4417    PrevSibling ps;
4418    ps.p = (PrevSibling *)p;
4419    ps.f = f;
4420
4421    //printf("checkEscapingSiblings(f = %s, outerfunc = %s)\n", f->toChars(), outerFunc->toChars());
4422    bool bAnyClosures = false;
4423    for (size_t i = 0; i < f->siblingCallers.dim; ++i)
4424    {
4425        FuncDeclaration *g = f->siblingCallers[i];
4426        if (g->isThis() || g->tookAddressOf)
4427        {
4428            markAsNeedingClosure(g, outerFunc);
4429            bAnyClosures = true;
4430        }
4431
4432        PrevSibling *prev = (PrevSibling *)p;
4433        while (1)
4434        {
4435            if (!prev)
4436            {
4437                bAnyClosures |= checkEscapingSiblings(g, outerFunc, &ps);
4438                break;
4439            }
4440            if (prev->f == g)
4441                break;
4442            prev = prev->p;
4443        }
4444    }
4445    //printf("\t%d\n", bAnyClosures);
4446    return bAnyClosures;
4447}
4448
4449
4450/*******************************
4451 * Look at all the variables in this function that are referenced
4452 * by nested functions, and determine if a closure needs to be
4453 * created for them.
4454 */
4455
4456bool FuncDeclaration::needsClosure()
4457{
4458    /* Need a closure for all the closureVars[] if any of the
4459     * closureVars[] are accessed by a
4460     * function that escapes the scope of this function.
4461     * We take the conservative approach and decide that a function needs
4462     * a closure if it:
4463     * 1) is a virtual function
4464     * 2) has its address taken
4465     * 3) has a parent that escapes
4466     * 4) calls another nested function that needs a closure
4467     *
4468     * Note that since a non-virtual function can be called by
4469     * a virtual one, if that non-virtual function accesses a closure
4470     * var, the closure still has to be taken. Hence, we check for isThis()
4471     * instead of isVirtual(). (thanks to David Friedman)
4472     *
4473     * When the function returns a local struct or class, `requiresClosure`
4474     * is already set to `true` upon entering this function when the
4475     * struct/class refers to a local variable and a closure is needed.
4476     */
4477
4478    //printf("FuncDeclaration::needsClosure() %s\n", toChars());
4479
4480    if (requiresClosure)
4481        goto Lyes;
4482
4483    for (size_t i = 0; i < closureVars.dim; i++)
4484    {
4485        VarDeclaration *v = closureVars[i];
4486        //printf("\tv = %s\n", v->toChars());
4487
4488        for (size_t j = 0; j < v->nestedrefs.dim; j++)
4489        {
4490            FuncDeclaration *f = v->nestedrefs[j];
4491            assert(f != this);
4492
4493            //printf("\t\tf = %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
4494
4495            /* Look to see if f escapes. We consider all parents of f within
4496             * this, and also all siblings which call f; if any of them escape,
4497             * so does f.
4498             * Mark all affected functions as requiring closures.
4499             */
4500            for (Dsymbol *s = f; s && s != this; s = s->parent)
4501            {
4502                FuncDeclaration *fx = s->isFuncDeclaration();
4503                if (!fx)
4504                    continue;
4505                if (fx->isThis() || fx->tookAddressOf)
4506                {
4507                    //printf("\t\tfx = %s, isVirtual=%d, isThis=%p, tookAddressOf=%d\n", fx->toChars(), fx->isVirtual(), fx->isThis(), fx->tookAddressOf);
4508
4509                    /* Mark as needing closure any functions between this and f
4510                     */
4511                    markAsNeedingClosure( (fx == f) ? fx->parent : fx, this);
4512
4513                    requiresClosure = true;
4514                }
4515
4516                /* We also need to check if any sibling functions that
4517                 * called us, have escaped. This is recursive: we need
4518                 * to check the callers of our siblings.
4519                 */
4520                if (checkEscapingSiblings(fx, this))
4521                    requiresClosure = true;
4522
4523                /* Bugzilla 12406: Iterate all closureVars to mark all descendant
4524                 * nested functions that access to the closing context of this funciton.
4525                 */
4526            }
4527        }
4528    }
4529    if (requiresClosure)
4530        goto Lyes;
4531
4532    return false;
4533
4534Lyes:
4535    //printf("\tneeds closure\n");
4536    return true;
4537}
4538
4539/***********************************************
4540 * Check that the function contains any closure.
4541 * If it's @nogc, report suitable errors.
4542 * This is mostly consistent with FuncDeclaration::needsClosure().
4543 *
4544 * Returns:
4545 *      true if any errors occur.
4546 */
4547bool FuncDeclaration::checkClosure()
4548{
4549    if (!needsClosure())
4550        return false;
4551
4552    if (setGC())
4553    {
4554        error("is @nogc yet allocates closures with the GC");
4555        if (global.gag)     // need not report supplemental errors
4556            return true;
4557    }
4558    else
4559    {
4560        printGCUsage(loc, "using closure causes GC allocation");
4561        return false;
4562    }
4563
4564    FuncDeclarations a;
4565    for (size_t i = 0; i < closureVars.dim; i++)
4566    {
4567        VarDeclaration *v = closureVars[i];
4568
4569        for (size_t j = 0; j < v->nestedrefs.dim; j++)
4570        {
4571            FuncDeclaration *f = v->nestedrefs[j];
4572            assert(f != this);
4573
4574            for (Dsymbol *s = f; s && s != this; s = s->parent)
4575            {
4576                FuncDeclaration *fx = s->isFuncDeclaration();
4577                if (!fx)
4578                    continue;
4579                if (fx->isThis() || fx->tookAddressOf)
4580                    goto Lfound;
4581                if (checkEscapingSiblings(fx, this))
4582                    goto Lfound;
4583            }
4584            continue;
4585
4586        Lfound:
4587            for (size_t k = 0; ; k++)
4588            {
4589                if (k == a.dim)
4590                {
4591                    a.push(f);
4592                    ::errorSupplemental(f->loc, "%s closes over variable %s at %s",
4593                        f->toPrettyChars(), v->toChars(), v->loc.toChars());
4594                    break;
4595                }
4596                if (a[k] == f)
4597                    break;
4598            }
4599            continue;
4600        }
4601    }
4602
4603    return true;
4604}
4605
4606/***********************************************
4607 * Determine if function's variables are referenced by a function
4608 * nested within it.
4609 */
4610
4611bool FuncDeclaration::hasNestedFrameRefs()
4612{
4613    if (closureVars.dim)
4614        return true;
4615
4616    /* If a virtual function has contracts, assume its variables are referenced
4617     * by those contracts, even if they aren't. Because they might be referenced
4618     * by the overridden or overriding function's contracts.
4619     * This can happen because frequire and fensure are implemented as nested functions,
4620     * and they can be called directly by an overriding function and the overriding function's
4621     * context had better match, or Bugzilla 7335 will bite.
4622     */
4623    if (fdrequire || fdensure)
4624        return true;
4625
4626    if (foverrides.dim && isVirtualMethod())
4627    {
4628        for (size_t i = 0; i < foverrides.dim; i++)
4629        {
4630            FuncDeclaration *fdv = foverrides[i];
4631            if (fdv->hasNestedFrameRefs())
4632                return true;
4633        }
4634    }
4635
4636    return false;
4637}
4638
4639/*********************************************
4640 * Return the function's parameter list, and whether
4641 * it is variadic or not.
4642 */
4643
4644Parameters *FuncDeclaration::getParameters(int *pvarargs)
4645{
4646    Parameters *fparameters = NULL;
4647    int fvarargs = 0;
4648
4649    if (type)
4650    {
4651        TypeFunction *fdtype = type->toTypeFunction();
4652        fparameters = fdtype->parameters;
4653        fvarargs = fdtype->varargs;
4654    }
4655    if (pvarargs)
4656        *pvarargs = fvarargs;
4657    return fparameters;
4658}
4659
4660
4661/****************************** FuncAliasDeclaration ************************/
4662
4663// Used as a way to import a set of functions from another scope into this one.
4664
4665FuncAliasDeclaration::FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads)
4666    : FuncDeclaration(funcalias->loc, funcalias->endloc, ident,
4667        funcalias->storage_class, funcalias->type)
4668{
4669    assert(funcalias != this);
4670    this->funcalias = funcalias;
4671
4672    this->hasOverloads = hasOverloads;
4673    if (hasOverloads)
4674    {
4675        if (FuncAliasDeclaration *fad = funcalias->isFuncAliasDeclaration())
4676            this->hasOverloads = fad->hasOverloads;
4677    }
4678    else
4679    {   // for internal use
4680        assert(!funcalias->isFuncAliasDeclaration());
4681        this->hasOverloads = false;
4682    }
4683    userAttribDecl = funcalias->userAttribDecl;
4684}
4685
4686const char *FuncAliasDeclaration::kind() const
4687{
4688    return "function alias";
4689}
4690
4691FuncDeclaration *FuncAliasDeclaration::toAliasFunc()
4692{
4693    return funcalias->toAliasFunc();
4694}
4695
4696
4697/****************************** FuncLiteralDeclaration ************************/
4698
4699FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
4700        TOK tok, ForeachStatement *fes, Identifier *id)
4701    : FuncDeclaration(loc, endloc, NULL, STCundefined, type)
4702{
4703    this->ident = id ? id : Id::empty;
4704    this->tok = tok;
4705    this->fes = fes;
4706    this->treq = NULL;
4707    this->deferToObj = false;
4708    //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
4709}
4710
4711Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s)
4712{
4713    //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars());
4714    assert(!s);
4715    FuncLiteralDeclaration *f = new FuncLiteralDeclaration(loc, endloc,
4716        type->syntaxCopy(), tok, fes, ident);
4717    f->treq = treq;     // don't need to copy
4718    return FuncDeclaration::syntaxCopy(f);
4719}
4720
4721bool FuncLiteralDeclaration::isNested()
4722{
4723    //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars());
4724    return (tok != TOKfunction) && !isThis();
4725}
4726
4727AggregateDeclaration *FuncLiteralDeclaration::isThis()
4728{
4729    //printf("FuncLiteralDeclaration::isThis() '%s'\n", toChars());
4730    return tok == TOKdelegate ? FuncDeclaration::isThis() : NULL;
4731}
4732
4733bool FuncLiteralDeclaration::isVirtual()
4734{
4735    return false;
4736}
4737
4738bool FuncLiteralDeclaration::addPreInvariant()
4739{
4740    return false;
4741}
4742
4743bool FuncLiteralDeclaration::addPostInvariant()
4744{
4745    return false;
4746}
4747
4748/*******************************
4749 * Modify all expression type of return statements to tret.
4750 *
4751 * On function literals, return type may be modified based on the context type
4752 * after its semantic3 is done, in FuncExp::implicitCastTo.
4753 *
4754 *  A function() dg = (){ return new B(); } // OK if is(B : A) == true
4755 *
4756 * If B to A conversion is convariant that requires offseet adjusting,
4757 * all return statements should be adjusted to return expressions typed A.
4758 */
4759void FuncLiteralDeclaration::modifyReturns(Scope *sc, Type *tret)
4760{
4761    class RetWalker : public StatementRewriteWalker
4762    {
4763    public:
4764        Scope *sc;
4765        Type *tret;
4766        FuncLiteralDeclaration *fld;
4767
4768        void visit(ReturnStatement *s)
4769        {
4770            Expression *exp = s->exp;
4771            if (exp && !exp->type->equals(tret))
4772            {
4773                s->exp = exp->castTo(sc, tret);
4774            }
4775        }
4776    };
4777
4778    if (semanticRun < PASSsemantic3done)
4779        return;
4780
4781    if (fes)
4782        return;
4783
4784    RetWalker w;
4785    w.sc = sc;
4786    w.tret = tret;
4787    w.fld = this;
4788    fbody->accept(&w);
4789
4790    // Also update the inferred function type to match the new return type.
4791    // This is required so the code generator does not try to cast the
4792    // modified returns back to the original type.
4793    if (inferRetType && type->nextOf() != tret)
4794        type->toTypeFunction()->next = tret;
4795}
4796
4797const char *FuncLiteralDeclaration::kind() const
4798{
4799    return (tok != TOKfunction) ? "delegate" : "function";
4800}
4801
4802const char *FuncLiteralDeclaration::toPrettyChars(bool QualifyTypes)
4803{
4804    if (parent)
4805    {
4806        TemplateInstance *ti = parent->isTemplateInstance();
4807        if (ti)
4808            return ti->tempdecl->toPrettyChars(QualifyTypes);
4809    }
4810    return Dsymbol::toPrettyChars(QualifyTypes);
4811}
4812
4813/********************************* CtorDeclaration ****************************/
4814
4815CtorDeclaration::CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type)
4816    : FuncDeclaration(loc, endloc, Id::ctor, stc, type)
4817{
4818    //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars());
4819}
4820
4821Dsymbol *CtorDeclaration::syntaxCopy(Dsymbol *s)
4822{
4823    assert(!s);
4824    CtorDeclaration *f = new CtorDeclaration(loc, endloc, storage_class, type->syntaxCopy());
4825    return FuncDeclaration::syntaxCopy(f);
4826}
4827
4828void CtorDeclaration::semantic(Scope *sc)
4829{
4830    //printf("CtorDeclaration::semantic() %s\n", toChars());
4831    if (semanticRun >= PASSsemanticdone)
4832        return;
4833    if (_scope)
4834    {
4835        sc = _scope;
4836        _scope = NULL;
4837    }
4838
4839    parent = sc->parent;
4840    Dsymbol *p = toParent2();
4841    AggregateDeclaration *ad = p->isAggregateDeclaration();
4842    if (!ad)
4843    {
4844        ::error(loc, "constructor can only be a member of aggregate, not %s %s",
4845            p->kind(), p->toChars());
4846        type = Type::terror;
4847        errors = true;
4848        return;
4849    }
4850
4851    sc = sc->push();
4852    sc->stc &= ~STCstatic;              // not a static constructor
4853    sc->flags |= SCOPEctor;
4854
4855    FuncDeclaration::semantic(sc);
4856
4857    sc->pop();
4858
4859    if (errors)
4860        return;
4861
4862    TypeFunction *tf = type->toTypeFunction();
4863
4864    /* See if it's the default constructor
4865     * But, template constructor should not become a default constructor.
4866     */
4867    if (ad && (!parent->isTemplateInstance() || parent->isTemplateMixin()))
4868    {
4869        const size_t dim = Parameter::dim(tf->parameters);
4870
4871        if (StructDeclaration *sd = ad->isStructDeclaration())
4872        {
4873            if (dim == 0 && tf->varargs == 0) // empty default ctor w/o any varargs
4874            {
4875                if (fbody || !(storage_class & STCdisable) || dim)
4876                {
4877                    error("default constructor for structs only allowed "
4878                        "with @disable, no body, and no parameters");
4879                    storage_class |= STCdisable;
4880                    fbody = NULL;
4881                }
4882                sd->noDefaultCtor = true;
4883            }
4884            else if (dim == 0 && tf->varargs) // allow varargs only ctor
4885            {
4886            }
4887            else if (dim && Parameter::getNth(tf->parameters, 0)->defaultArg)
4888            {
4889                // if the first parameter has a default argument, then the rest does as well
4890                if (storage_class & STCdisable)
4891                {
4892                    deprecation("@disable'd constructor cannot have default "
4893                                "arguments for all parameters.");
4894                    deprecationSupplemental(loc, "Use @disable this(); if you want to disable default initialization.");
4895                }
4896                else
4897                    deprecation("all parameters have default arguments, "
4898                                "but structs cannot have default constructors.");
4899            }
4900
4901        }
4902        else if (dim == 0 && tf->varargs == 0)
4903        {
4904            ad->defaultCtor = this;
4905        }
4906    }
4907}
4908
4909const char *CtorDeclaration::kind() const
4910{
4911    return "constructor";
4912}
4913
4914const char *CtorDeclaration::toChars()
4915{
4916    return "this";
4917}
4918
4919bool CtorDeclaration::isVirtual()
4920{
4921    return false;
4922}
4923
4924bool CtorDeclaration::addPreInvariant()
4925{
4926    return false;
4927}
4928
4929bool CtorDeclaration::addPostInvariant()
4930{
4931    return (isThis() && vthis && global.params.useInvariants);
4932}
4933
4934
4935/********************************* PostBlitDeclaration ****************************/
4936
4937PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
4938    : FuncDeclaration(loc, endloc, id, stc, NULL)
4939{
4940}
4941
4942Dsymbol *PostBlitDeclaration::syntaxCopy(Dsymbol *s)
4943{
4944    assert(!s);
4945    PostBlitDeclaration *dd = new PostBlitDeclaration(loc, endloc, storage_class, ident);
4946    return FuncDeclaration::syntaxCopy(dd);
4947}
4948
4949void PostBlitDeclaration::semantic(Scope *sc)
4950{
4951    //printf("PostBlitDeclaration::semantic() %s\n", toChars());
4952    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
4953    //printf("stc = x%llx\n", sc->stc);
4954    if (semanticRun >= PASSsemanticdone)
4955        return;
4956    if (_scope)
4957    {
4958        sc = _scope;
4959        _scope = NULL;
4960    }
4961
4962    parent = sc->parent;
4963    Dsymbol *p = toParent2();
4964    StructDeclaration *ad = p->isStructDeclaration();
4965    if (!ad)
4966    {
4967        ::error(loc, "postblit can only be a member of struct/union, not %s %s",
4968            p->kind(), p->toChars());
4969        type = Type::terror;
4970        errors = true;
4971        return;
4972    }
4973    if (ident == Id::postblit && semanticRun < PASSsemantic)
4974        ad->postblits.push(this);
4975    if (!type)
4976        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
4977
4978    sc = sc->push();
4979    sc->stc &= ~STCstatic;              // not static
4980    sc->linkage = LINKd;
4981
4982    FuncDeclaration::semantic(sc);
4983
4984    sc->pop();
4985}
4986
4987bool PostBlitDeclaration::overloadInsert(Dsymbol *)
4988{
4989    return false;       // cannot overload postblits
4990}
4991
4992bool PostBlitDeclaration::addPreInvariant()
4993{
4994    return false;
4995}
4996
4997bool PostBlitDeclaration::addPostInvariant()
4998{
4999    return (isThis() && vthis && global.params.useInvariants);
5000}
5001
5002bool PostBlitDeclaration::isVirtual()
5003{
5004    return false;
5005}
5006
5007/********************************* DtorDeclaration ****************************/
5008
5009DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc)
5010    : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL)
5011{
5012}
5013
5014DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
5015    : FuncDeclaration(loc, endloc, id, stc, NULL)
5016{
5017}
5018
5019Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s)
5020{
5021    assert(!s);
5022    DtorDeclaration *dd = new DtorDeclaration(loc, endloc, storage_class, ident);
5023    return FuncDeclaration::syntaxCopy(dd);
5024}
5025
5026void DtorDeclaration::semantic(Scope *sc)
5027{
5028    //printf("DtorDeclaration::semantic() %s\n", toChars());
5029    //printf("ident: %s, %s, %p, %p\n", ident->toChars(), Id::dtor->toChars(), ident, Id::dtor);
5030    if (semanticRun >= PASSsemanticdone)
5031        return;
5032    if (_scope)
5033    {
5034        sc = _scope;
5035        _scope = NULL;
5036    }
5037
5038    parent = sc->parent;
5039    Dsymbol *p = toParent2();
5040    AggregateDeclaration *ad = p->isAggregateDeclaration();
5041    if (!ad)
5042    {
5043        ::error(loc, "destructor can only be a member of aggregate, not %s %s",
5044            p->kind(), p->toChars());
5045        type = Type::terror;
5046        errors = true;
5047        return;
5048    }
5049    if (ident == Id::dtor && semanticRun < PASSsemantic)
5050        ad->dtors.push(this);
5051    if (!type)
5052        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
5053
5054    sc = sc->push();
5055    sc->stc &= ~STCstatic;              // not a static destructor
5056    if (sc->linkage != LINKcpp)
5057        sc->linkage = LINKd;
5058
5059    FuncDeclaration::semantic(sc);
5060
5061    sc->pop();
5062}
5063
5064bool DtorDeclaration::overloadInsert(Dsymbol *)
5065{
5066    return false;       // cannot overload destructors
5067}
5068
5069bool DtorDeclaration::addPreInvariant()
5070{
5071    return (isThis() && vthis && global.params.useInvariants);
5072}
5073
5074bool DtorDeclaration::addPostInvariant()
5075{
5076    return false;
5077}
5078
5079const char *DtorDeclaration::kind() const
5080{
5081    return "destructor";
5082}
5083
5084const char *DtorDeclaration::toChars()
5085{
5086    return "~this";
5087}
5088
5089bool DtorDeclaration::isVirtual()
5090{
5091    // false so that dtor's don't get put into the vtbl[]
5092    return false;
5093}
5094
5095/********************************* StaticCtorDeclaration ****************************/
5096
5097StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
5098    : FuncDeclaration(loc, endloc,
5099      Identifier::generateId("_staticCtor"), STCstatic | stc, NULL)
5100{
5101}
5102
5103StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc)
5104    : FuncDeclaration(loc, endloc,
5105      Identifier::generateId(name), STCstatic | stc, NULL)
5106{
5107}
5108
5109Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s)
5110{
5111    assert(!s);
5112    StaticCtorDeclaration *scd = new StaticCtorDeclaration(loc, endloc, storage_class);
5113    return FuncDeclaration::syntaxCopy(scd);
5114}
5115
5116void StaticCtorDeclaration::semantic(Scope *sc)
5117{
5118    //printf("StaticCtorDeclaration::semantic()\n");
5119    if (semanticRun >= PASSsemanticdone)
5120        return;
5121    if (_scope)
5122    {
5123        sc = _scope;
5124        _scope = NULL;
5125    }
5126
5127    parent = sc->parent;
5128    Dsymbol *p = parent->pastMixin();
5129    if (!p->isScopeDsymbol())
5130    {
5131        const char *s = (isSharedStaticCtorDeclaration() ? "shared " : "");
5132        ::error(loc, "%sstatic constructor can only be member of module/aggregate/template, not %s %s",
5133            s, p->kind(), p->toChars());
5134        type = Type::terror;
5135        errors = true;
5136        return;
5137    }
5138    if (!type)
5139        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
5140
5141    /* If the static ctor appears within a template instantiation,
5142     * it could get called multiple times by the module constructors
5143     * for different modules. Thus, protect it with a gate.
5144     */
5145    if (isInstantiated() && semanticRun < PASSsemantic)
5146    {
5147        /* Add this prefix to the function:
5148         *      static int gate;
5149         *      if (++gate != 1) return;
5150         * Note that this is not thread safe; should not have threads
5151         * during static construction.
5152         */
5153        VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, Id::gate, NULL);
5154        v->storage_class = STCtemp | (isSharedStaticCtorDeclaration() ? STCstatic : STCtls);
5155        Statements *sa = new Statements();
5156        Statement *s = new ExpStatement(Loc(), v);
5157        sa->push(s);
5158        Expression *e = new IdentifierExp(Loc(), v->ident);
5159        e = new AddAssignExp(Loc(), e, new IntegerExp(1));
5160        e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(1));
5161        s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL, Loc());
5162        sa->push(s);
5163        if (fbody)
5164            sa->push(fbody);
5165        fbody = new CompoundStatement(Loc(), sa);
5166    }
5167
5168    FuncDeclaration::semantic(sc);
5169
5170    // We're going to need ModuleInfo
5171    Module *m = getModule();
5172    if (!m)
5173        m = sc->_module;
5174    if (m)
5175    {
5176        m->needmoduleinfo = 1;
5177        //printf("module1 %s needs moduleinfo\n", m->toChars());
5178    }
5179}
5180
5181AggregateDeclaration *StaticCtorDeclaration::isThis()
5182{
5183    return NULL;
5184}
5185
5186bool StaticCtorDeclaration::isVirtual()
5187{
5188    return false;
5189}
5190
5191bool StaticCtorDeclaration::hasStaticCtorOrDtor()
5192{
5193    return true;
5194}
5195
5196bool StaticCtorDeclaration::addPreInvariant()
5197{
5198    return false;
5199}
5200
5201bool StaticCtorDeclaration::addPostInvariant()
5202{
5203    return false;
5204}
5205
5206/********************************* SharedStaticCtorDeclaration ****************************/
5207
5208SharedStaticCtorDeclaration::SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
5209    : StaticCtorDeclaration(loc, endloc, "_sharedStaticCtor", stc)
5210{
5211}
5212
5213Dsymbol *SharedStaticCtorDeclaration::syntaxCopy(Dsymbol *s)
5214{
5215    assert(!s);
5216    SharedStaticCtorDeclaration *scd = new SharedStaticCtorDeclaration(loc, endloc, storage_class);
5217    return FuncDeclaration::syntaxCopy(scd);
5218}
5219
5220/********************************* StaticDtorDeclaration ****************************/
5221
5222StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
5223    : FuncDeclaration(loc, endloc,
5224      Identifier::generateId("_staticDtor"), STCstatic | stc, NULL)
5225{
5226    vgate = NULL;
5227}
5228
5229StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc)
5230    : FuncDeclaration(loc, endloc,
5231      Identifier::generateId(name), STCstatic | stc, NULL)
5232{
5233    vgate = NULL;
5234}
5235
5236Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
5237{
5238    assert(!s);
5239    StaticDtorDeclaration *sdd = new StaticDtorDeclaration(loc, endloc, storage_class);
5240    return FuncDeclaration::syntaxCopy(sdd);
5241}
5242
5243void StaticDtorDeclaration::semantic(Scope *sc)
5244{
5245    if (semanticRun >= PASSsemanticdone)
5246        return;
5247    if (_scope)
5248    {
5249        sc = _scope;
5250        _scope = NULL;
5251    }
5252
5253    parent = sc->parent;
5254    Dsymbol *p = parent->pastMixin();
5255    if (!p->isScopeDsymbol())
5256    {
5257        const char *s = (isSharedStaticDtorDeclaration() ? "shared " : "");
5258        ::error(loc, "%sstatic destructor can only be member of module/aggregate/template, not %s %s",
5259            s, p->kind(), p->toChars());
5260        type = Type::terror;
5261        errors = true;
5262        return;
5263    }
5264    if (!type)
5265        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
5266
5267    /* If the static ctor appears within a template instantiation,
5268     * it could get called multiple times by the module constructors
5269     * for different modules. Thus, protect it with a gate.
5270     */
5271    if (isInstantiated() && semanticRun < PASSsemantic)
5272    {
5273        /* Add this prefix to the function:
5274         *      static int gate;
5275         *      if (--gate != 0) return;
5276         * Increment gate during constructor execution.
5277         * Note that this is not thread safe; should not have threads
5278         * during static destruction.
5279         */
5280        VarDeclaration *v = new VarDeclaration(Loc(), Type::tint32, Id::gate, NULL);
5281        v->storage_class = STCtemp | (isSharedStaticDtorDeclaration() ? STCstatic : STCtls);
5282        Statements *sa = new Statements();
5283        Statement *s = new ExpStatement(Loc(), v);
5284        sa->push(s);
5285        Expression *e = new IdentifierExp(Loc(), v->ident);
5286        e = new AddAssignExp(Loc(), e, new IntegerExp(-1));
5287        e = new EqualExp(TOKnotequal, Loc(), e, new IntegerExp(0));
5288        s = new IfStatement(Loc(), NULL, e, new ReturnStatement(Loc(), NULL), NULL, Loc());
5289        sa->push(s);
5290        if (fbody)
5291            sa->push(fbody);
5292        fbody = new CompoundStatement(Loc(), sa);
5293        vgate = v;
5294    }
5295
5296    FuncDeclaration::semantic(sc);
5297
5298    // We're going to need ModuleInfo
5299    Module *m = getModule();
5300    if (!m)
5301        m = sc->_module;
5302    if (m)
5303    {
5304        m->needmoduleinfo = 1;
5305        //printf("module2 %s needs moduleinfo\n", m->toChars());
5306    }
5307}
5308
5309AggregateDeclaration *StaticDtorDeclaration::isThis()
5310{
5311    return NULL;
5312}
5313
5314bool StaticDtorDeclaration::isVirtual()
5315{
5316    return false;
5317}
5318
5319bool StaticDtorDeclaration::hasStaticCtorOrDtor()
5320{
5321    return true;
5322}
5323
5324bool StaticDtorDeclaration::addPreInvariant()
5325{
5326    return false;
5327}
5328
5329bool StaticDtorDeclaration::addPostInvariant()
5330{
5331    return false;
5332}
5333
5334/********************************* SharedStaticDtorDeclaration ****************************/
5335
5336SharedStaticDtorDeclaration::SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc)
5337    : StaticDtorDeclaration(loc, endloc, "_sharedStaticDtor", stc)
5338{
5339}
5340
5341Dsymbol *SharedStaticDtorDeclaration::syntaxCopy(Dsymbol *s)
5342{
5343    assert(!s);
5344    SharedStaticDtorDeclaration *sdd = new SharedStaticDtorDeclaration(loc, endloc, storage_class);
5345    return FuncDeclaration::syntaxCopy(sdd);
5346}
5347
5348/********************************* InvariantDeclaration ****************************/
5349
5350InvariantDeclaration::InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id)
5351    : FuncDeclaration(loc, endloc,
5352                      id ? id : Identifier::generateId("__invariant"),
5353                      stc, NULL)
5354{
5355}
5356
5357Dsymbol *InvariantDeclaration::syntaxCopy(Dsymbol *s)
5358{
5359    assert(!s);
5360    InvariantDeclaration *id = new InvariantDeclaration(loc, endloc, storage_class);
5361    return FuncDeclaration::syntaxCopy(id);
5362}
5363
5364void InvariantDeclaration::semantic(Scope *sc)
5365{
5366    if (semanticRun >= PASSsemanticdone)
5367        return;
5368    if (_scope)
5369    {
5370        sc = _scope;
5371        _scope = NULL;
5372    }
5373
5374    parent = sc->parent;
5375    Dsymbol *p = parent->pastMixin();
5376    AggregateDeclaration *ad = p->isAggregateDeclaration();
5377    if (!ad)
5378    {
5379        ::error(loc, "invariant can only be a member of aggregate, not %s %s",
5380            p->kind(), p->toChars());
5381        type = Type::terror;
5382        errors = true;
5383        return;
5384    }
5385    if (ident != Id::classInvariant &&
5386        semanticRun < PASSsemantic &&
5387        !ad->isUnionDeclaration()           // users are on their own with union fields
5388       )
5389        ad->invs.push(this);
5390    if (!type)
5391        type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
5392
5393    sc = sc->push();
5394    sc->stc &= ~STCstatic;              // not a static invariant
5395    sc->stc |= STCconst;                // invariant() is always const
5396    sc->flags = (sc->flags & ~SCOPEcontract) | SCOPEinvariant;
5397    sc->linkage = LINKd;
5398
5399    FuncDeclaration::semantic(sc);
5400
5401    sc->pop();
5402}
5403
5404bool InvariantDeclaration::isVirtual()
5405{
5406    return false;
5407}
5408
5409bool InvariantDeclaration::addPreInvariant()
5410{
5411    return false;
5412}
5413
5414bool InvariantDeclaration::addPostInvariant()
5415{
5416    return false;
5417}
5418
5419/********************************* UnitTestDeclaration ****************************/
5420
5421/*******************************
5422 * Generate unique unittest function Id so we can have multiple
5423 * instances per module.
5424 */
5425
5426static Identifier *unitTestId(Loc loc)
5427{
5428    OutBuffer buf;
5429    buf.printf("__unittestL%u_", loc.linnum);
5430    return Identifier::generateId(buf.peekString());
5431}
5432
5433UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc)
5434    : FuncDeclaration(loc, endloc, unitTestId(loc), stc, NULL)
5435{
5436    this->codedoc = codedoc;
5437}
5438
5439Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
5440{
5441    assert(!s);
5442    UnitTestDeclaration *utd = new UnitTestDeclaration(loc, endloc, storage_class, codedoc);
5443    return FuncDeclaration::syntaxCopy(utd);
5444}
5445
5446void UnitTestDeclaration::semantic(Scope *sc)
5447{
5448    if (semanticRun >= PASSsemanticdone)
5449        return;
5450    if (_scope)
5451    {
5452        sc = _scope;
5453        _scope = NULL;
5454    }
5455
5456    protection = sc->protection;
5457
5458    parent = sc->parent;
5459    Dsymbol *p = parent->pastMixin();
5460    if (!p->isScopeDsymbol())
5461    {
5462        ::error(loc, "unittest can only be a member of module/aggregate/template, not %s %s",
5463            p->kind(), p->toChars());
5464        type = Type::terror;
5465        errors = true;
5466        return;
5467    }
5468
5469    if (global.params.useUnitTests)
5470    {
5471        if (!type)
5472            type = new TypeFunction(NULL, Type::tvoid, false, LINKd, storage_class);
5473        Scope *sc2 = sc->push();
5474        sc2->linkage = LINKd;
5475        FuncDeclaration::semantic(sc2);
5476        sc2->pop();
5477    }
5478}
5479
5480AggregateDeclaration *UnitTestDeclaration::isThis()
5481{
5482    return NULL;
5483}
5484
5485bool UnitTestDeclaration::isVirtual()
5486{
5487    return false;
5488}
5489
5490bool UnitTestDeclaration::addPreInvariant()
5491{
5492    return false;
5493}
5494
5495bool UnitTestDeclaration::addPostInvariant()
5496{
5497    return false;
5498}
5499
5500/********************************* NewDeclaration ****************************/
5501
5502NewDeclaration::NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams, int varargs)
5503    : FuncDeclaration(loc, endloc, Id::classNew, STCstatic | stc, NULL)
5504{
5505    this->parameters = fparams;
5506    this->varargs = varargs;
5507}
5508
5509Dsymbol *NewDeclaration::syntaxCopy(Dsymbol *s)
5510{
5511    assert(!s);
5512    NewDeclaration *f = new NewDeclaration(loc, endloc,
5513        storage_class, Parameter::arraySyntaxCopy(parameters), varargs);
5514    return FuncDeclaration::syntaxCopy(f);
5515}
5516
5517void NewDeclaration::semantic(Scope *sc)
5518{
5519    //printf("NewDeclaration::semantic()\n");
5520    if (semanticRun >= PASSsemanticdone)
5521        return;
5522    if (_scope)
5523    {
5524        sc = _scope;
5525        _scope = NULL;
5526    }
5527
5528    parent = sc->parent;
5529    Dsymbol *p = parent->pastMixin();
5530    if (!p->isAggregateDeclaration())
5531    {
5532        ::error(loc, "allocator can only be a member of aggregate, not %s %s",
5533            p->kind(), p->toChars());
5534        type = Type::terror;
5535        errors = true;
5536        return;
5537    }
5538    Type *tret = Type::tvoid->pointerTo();
5539    if (!type)
5540        type = new TypeFunction(parameters, tret, varargs, LINKd, storage_class);
5541
5542    type = type->semantic(loc, sc);
5543
5544    // Check that there is at least one argument of type size_t
5545    TypeFunction *tf = type->toTypeFunction();
5546    if (Parameter::dim(tf->parameters) < 1)
5547    {
5548        error("at least one argument of type size_t expected");
5549    }
5550    else
5551    {
5552        Parameter *fparam = Parameter::getNth(tf->parameters, 0);
5553        if (!fparam->type->equals(Type::tsize_t))
5554            error("first argument must be type size_t, not %s", fparam->type->toChars());
5555    }
5556
5557    FuncDeclaration::semantic(sc);
5558}
5559
5560const char *NewDeclaration::kind() const
5561{
5562    return "allocator";
5563}
5564
5565bool NewDeclaration::isVirtual()
5566{
5567    return false;
5568}
5569
5570bool NewDeclaration::addPreInvariant()
5571{
5572    return false;
5573}
5574
5575bool NewDeclaration::addPostInvariant()
5576{
5577    return false;
5578}
5579
5580/********************************* DeleteDeclaration ****************************/
5581
5582DeleteDeclaration::DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *fparams)
5583    : FuncDeclaration(loc, endloc, Id::classDelete, STCstatic | stc, NULL)
5584{
5585    this->parameters = fparams;
5586}
5587
5588Dsymbol *DeleteDeclaration::syntaxCopy(Dsymbol *s)
5589{
5590    assert(!s);
5591    DeleteDeclaration *f = new DeleteDeclaration(loc, endloc,
5592            storage_class, Parameter::arraySyntaxCopy(parameters));
5593    return FuncDeclaration::syntaxCopy(f);
5594}
5595
5596void DeleteDeclaration::semantic(Scope *sc)
5597{
5598    //printf("DeleteDeclaration::semantic()\n");
5599    if (semanticRun >= PASSsemanticdone)
5600        return;
5601    if (_scope)
5602    {
5603        sc = _scope;
5604        _scope = NULL;
5605    }
5606
5607    parent = sc->parent;
5608    Dsymbol *p = parent->pastMixin();
5609    if (!p->isAggregateDeclaration())
5610    {
5611        ::error(loc, "deallocator can only be a member of aggregate, not %s %s",
5612            p->kind(), p->toChars());
5613        type = Type::terror;
5614        errors = true;
5615        return;
5616    }
5617    if (!type)
5618        type = new TypeFunction(parameters, Type::tvoid, 0, LINKd, storage_class);
5619
5620    type = type->semantic(loc, sc);
5621
5622    // Check that there is only one argument of type void*
5623    TypeFunction *tf = type->toTypeFunction();
5624    if (Parameter::dim(tf->parameters) != 1)
5625    {
5626        error("one argument of type void* expected");
5627    }
5628    else
5629    {
5630        Parameter *fparam = Parameter::getNth(tf->parameters, 0);
5631        if (!fparam->type->equals(Type::tvoid->pointerTo()))
5632            error("one argument of type void* expected, not %s", fparam->type->toChars());
5633    }
5634
5635    FuncDeclaration::semantic(sc);
5636}
5637
5638const char *DeleteDeclaration::kind() const
5639{
5640    return "deallocator";
5641}
5642
5643bool DeleteDeclaration::isDelete()
5644{
5645    return true;
5646}
5647
5648bool DeleteDeclaration::isVirtual()
5649{
5650    return false;
5651}
5652
5653bool DeleteDeclaration::addPreInvariant()
5654{
5655    return false;
5656}
5657
5658bool DeleteDeclaration::addPostInvariant()
5659{
5660    return false;
5661}
5662