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