1 /**
2  * Does the semantic 1 pass on the AST, which looks at symbol declarations but not initializers
3  * or function bodies.
4  *
5  * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
6  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
7  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d)
9  * Documentation:  https://dlang.org/phobos/dmd_dsymbolsem.html
10  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dsymbolsem.d
11  */
12 
13 module dmd.dsymbolsem;
14 
15 import core.stdc.stdio;
16 import core.stdc.string;
17 
18 import dmd.aggregate;
19 import dmd.aliasthis;
20 import dmd.arraytypes;
21 import dmd.astcodegen;
22 import dmd.attrib;
23 import dmd.blockexit;
24 import dmd.clone;
25 import dmd.compiler;
26 import dmd.dcast;
27 import dmd.dclass;
28 import dmd.declaration;
29 import dmd.denum;
30 import dmd.dimport;
31 import dmd.dinterpret;
32 import dmd.dmangle;
33 import dmd.dmodule;
34 import dmd.dscope;
35 import dmd.dstruct;
36 import dmd.dsymbol;
37 import dmd.dtemplate;
38 import dmd.dversion;
39 import dmd.errors;
40 import dmd.escape;
41 import dmd.expression;
42 import dmd.expressionsem;
43 import dmd.func;
44 import dmd.globals;
45 import dmd.id;
46 import dmd.identifier;
47 import dmd.init;
48 import dmd.initsem;
49 import dmd.hdrgen;
50 import dmd.mtype;
51 import dmd.nogc;
52 import dmd.nspace;
53 import dmd.objc;
54 import dmd.opover;
55 import dmd.parse;
56 import dmd.root.filename;
57 import dmd.root.outbuffer;
58 import dmd.root.rmem;
59 import dmd.root.rootobject;
60 import dmd.semantic2;
61 import dmd.semantic3;
62 import dmd.sideeffect;
63 import dmd.statementsem;
64 import dmd.staticassert;
65 import dmd.tokens;
66 import dmd.utf;
67 import dmd.utils;
68 import dmd.statement;
69 import dmd.target;
70 import dmd.templateparamsem;
71 import dmd.typesem;
72 import dmd.visitor;
73 
74 enum LOG = false;
75 
76 /*****************************************
77  * Create inclusive postblit for struct by aggregating
78  * all the postblits in postblits[] with the postblits for
79  * all the members.
80  * Note the close similarity with AggregateDeclaration::buildDtor(),
81  * and the ordering changes (runs forward instead of backwards).
82  */
83 private FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
84 {
85     //printf("StructDeclaration::buildPostBlit() %s\n", sd.toChars());
86     if (sd.isUnionDeclaration())
87         return null;
88 
89     // by default, the storage class of the created postblit
90     StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
91     Loc declLoc = sd.postblits.dim ? sd.postblits[0].loc : sd.loc;
92     Loc loc; // internal code should have no loc to prevent coverage
93 
94     // if any of the postblits are disabled, then the generated postblit
95     // will be disabled
96     for (size_t i = 0; i < sd.postblits.dim; i++)
97     {
98         stc |= sd.postblits[i].storage_class & STC.disable;
99     }
100 
101     VarDeclaration[] fieldsToDestroy;
102     auto postblitCalls = new Statements();
103     // iterate through all the struct fields that are not disabled
104     for (size_t i = 0; i < sd.fields.dim && !(stc & STC.disable); i++)
105     {
106         auto structField = sd.fields[i];
107         if (structField.storage_class & STC.ref_)
108             continue;
109         if (structField.overlapped)
110             continue;
111         // if it's a struct declaration or an array of structs
112         Type tv = structField.type.baseElemOf();
113         if (tv.ty != Tstruct)
114             continue;
115         auto sdv = (cast(TypeStruct)tv).sym;
116         // which has a postblit declaration
117         if (!sdv.postblit)
118             continue;
119         assert(!sdv.isUnionDeclaration());
120 
121         // if this field's postblit is not `nothrow`, add a `scope(failure)`
122         // block to destroy any prior successfully postblitted fields should
123         // this field's postblit fail
124         if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow)
125         {
126              // create a list of destructors that need to be called
127             Expression[] dtorCalls;
128             foreach(sf; fieldsToDestroy)
129             {
130                 Expression ex;
131                 tv = sf.type.toBasetype();
132                 if (tv.ty == Tstruct)
133                 {
134                     // this.v.__xdtor()
135 
136                     ex = new ThisExp(loc);
137                     ex = new DotVarExp(loc, ex, sf);
138 
139                     // This is a hack so we can call destructors on const/immutable objects.
140                     ex = new AddrExp(loc, ex);
141                     ex = new CastExp(loc, ex, sf.type.mutableOf().pointerTo());
142                     ex = new PtrExp(loc, ex);
143                     if (stc & STC.safe)
144                         stc = (stc & ~STC.safe) | STC.trusted;
145 
146                     auto sfv = (cast(TypeStruct)sf.type.baseElemOf()).sym;
147 
148                     ex = new DotVarExp(loc, ex, sfv.dtor, false);
149                     ex = new CallExp(loc, ex);
150 
151                     dtorCalls ~= ex;
152                 }
153                 else
154                 {
155                     // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
156 
157                     const length = tv.numberOfElems(loc);
158 
159                     ex = new ThisExp(loc);
160                     ex = new DotVarExp(loc, ex, sf);
161 
162                     // This is a hack so we can call destructors on const/immutable objects.
163                     ex = new DotIdExp(loc, ex, Id.ptr);
164                     ex = new CastExp(loc, ex, sdv.type.pointerTo());
165                     if (stc & STC.safe)
166                         stc = (stc & ~STC.safe) | STC.trusted;
167 
168                     auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
169                                                     new IntegerExp(loc, length, Type.tsize_t));
170                     // Prevent redundant bounds check
171                     se.upperIsInBounds = true;
172                     se.lowerIsLessThanUpper = true;
173 
174                     ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se);
175 
176                     dtorCalls ~= ex;
177                 }
178             }
179             fieldsToDestroy = [];
180 
181             // aggregate the destructor calls
182             auto dtors = new Statements();
183             foreach_reverse(dc; dtorCalls)
184             {
185                 dtors.push(new ExpStatement(loc, dc));
186             }
187 
188             // put destructor calls in a `scope(failure)` block
189             postblitCalls.push(new ScopeGuardStatement(loc, TOK.onScopeFailure, new CompoundStatement(loc, dtors)));
190         }
191 
192         // perform semantic on the member postblit in order to
193         // be able to aggregate it later on with the rest of the
194         // postblits
195         sdv.postblit.functionSemantic();
196 
197         stc = mergeFuncAttrs(stc, sdv.postblit);
198         stc = mergeFuncAttrs(stc, sdv.dtor);
199 
200         // if any of the struct member fields has disabled
201         // its postblit, then `sd` is not copyable, so no
202         // postblit is generated
203         if (stc & STC.disable)
204         {
205             postblitCalls.setDim(0);
206             break;
207         }
208 
209         Expression ex;
210         tv = structField.type.toBasetype();
211         if (tv.ty == Tstruct)
212         {
213             // this.v.__xpostblit()
214 
215             ex = new ThisExp(loc);
216             ex = new DotVarExp(loc, ex, structField);
217 
218             // This is a hack so we can call postblits on const/immutable objects.
219             ex = new AddrExp(loc, ex);
220             ex = new CastExp(loc, ex, structField.type.mutableOf().pointerTo());
221             ex = new PtrExp(loc, ex);
222             if (stc & STC.safe)
223                 stc = (stc & ~STC.safe) | STC.trusted;
224 
225             ex = new DotVarExp(loc, ex, sdv.postblit, false);
226             ex = new CallExp(loc, ex);
227         }
228         else
229         {
230             // _ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])
231 
232             const length = tv.numberOfElems(loc);
233             if (length == 0)
234                 continue;
235 
236             ex = new ThisExp(loc);
237             ex = new DotVarExp(loc, ex, structField);
238 
239             // This is a hack so we can call postblits on const/immutable objects.
240             ex = new DotIdExp(loc, ex, Id.ptr);
241             ex = new CastExp(loc, ex, sdv.type.pointerTo());
242             if (stc & STC.safe)
243                 stc = (stc & ~STC.safe) | STC.trusted;
244 
245             auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
246                                             new IntegerExp(loc, length, Type.tsize_t));
247             // Prevent redundant bounds check
248             se.upperIsInBounds = true;
249             se.lowerIsLessThanUpper = true;
250             ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayPostblit), se);
251         }
252         postblitCalls.push(new ExpStatement(loc, ex)); // combine in forward order
253 
254         /* https://issues.dlang.org/show_bug.cgi?id=10972
255          * When subsequent field postblit calls fail,
256          * this field should be destructed for Exception Safety.
257          */
258         if (sdv.dtor)
259         {
260             sdv.dtor.functionSemantic();
261 
262             // keep a list of fields that need to be destroyed in case
263             // of a future postblit failure
264             fieldsToDestroy ~= structField;
265         }
266     }
267 
268     void checkShared()
269     {
270         if (sd.type.isShared())
271             stc |= STC.shared_;
272     }
273 
274     // Build our own "postblit" which executes a, but only if needed.
275     if (postblitCalls.dim || (stc & STC.disable))
276     {
277         //printf("Building __fieldPostBlit()\n");
278         checkShared();
279         auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit);
280         dd.generated = true;
281         dd.storage_class |= STC.inference;
282         dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls);
283         sd.postblits.shift(dd);
284         sd.members.push(dd);
285         dd.dsymbolSemantic(sc);
286     }
287 
288     // create __xpostblit, which is the generated postblit
289     FuncDeclaration xpostblit = null;
290     switch (sd.postblits.dim)
291     {
292     case 0:
293         break;
294 
295     case 1:
296         xpostblit = sd.postblits[0];
297         break;
298 
299     default:
300         Expression e = null;
301         stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
302         for (size_t i = 0; i < sd.postblits.dim; i++)
303         {
304             auto fd = sd.postblits[i];
305             stc = mergeFuncAttrs(stc, fd);
306             if (stc & STC.disable)
307             {
308                 e = null;
309                 break;
310             }
311             Expression ex = new ThisExp(loc);
312             ex = new DotVarExp(loc, ex, fd, false);
313             ex = new CallExp(loc, ex);
314             e = Expression.combine(e, ex);
315         }
316 
317         checkShared();
318         auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit);
319         dd.generated = true;
320         dd.storage_class |= STC.inference;
321         dd.fbody = new ExpStatement(loc, e);
322         sd.members.push(dd);
323         dd.dsymbolSemantic(sc);
324         xpostblit = dd;
325         break;
326     }
327 
328     // Add an __xpostblit alias to make the inclusive postblit accessible
329     if (xpostblit)
330     {
331         auto _alias = new AliasDeclaration(Loc.initial, Id.__xpostblit, xpostblit);
332         _alias.dsymbolSemantic(sc);
333         sd.members.push(_alias);
334         _alias.addMember(sc, sd); // add to symbol table
335     }
336     return xpostblit;
337 }
338 
339 /**
340  * Generates a copy constructor declaration with the specified storage
341  * class for the parameter and the function.
342  *
343  * Params:
344  *  sd = the `struct` that contains the copy constructor
345  *  paramStc = the storage class of the copy constructor parameter
346  *  funcStc = the storage class for the copy constructor declaration
347  *
348  * Returns:
349  *  The copy constructor declaration for struct `sd`.
350  */
351 private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc)
352 {
353     auto fparams = new Parameters();
354     auto structType = sd.type;
355     fparams.push(new Parameter(paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
356     ParameterList pList = ParameterList(fparams);
357     auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_);
358     auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true);
359     ccd.storage_class |= funcStc;
360     ccd.storage_class |= STC.inference;
361     ccd.generated = true;
362     return ccd;
363 }
364 
365 /**
366  * Generates a trivial copy constructor body that simply does memberwise
367  * initialization:
368  *
369  *    this.field1 = rhs.field1;
370  *    this.field2 = rhs.field2;
371  *    ...
372  *
373  * Params:
374  *  sd = the `struct` declaration that contains the copy constructor
375  *
376  * Returns:
377  *  A `CompoundStatement` containing the body of the copy constructor.
378  */
379 private Statement generateCopyCtorBody(StructDeclaration sd)
380 {
381     Loc loc;
382     Expression e;
383     foreach (v; sd.fields)
384     {
385         auto ec = new AssignExp(loc,
386             new DotVarExp(loc, new ThisExp(loc), v),
387             new DotVarExp(loc, new IdentifierExp(loc, Id.p), v));
388         e = Expression.combine(e, ec);
389         //printf("e.toChars = %s\n", e.toChars());
390     }
391     Statement s1 = new ExpStatement(loc, e);
392     return new CompoundStatement(loc, s1);
393 }
394 
395 /**
396  * Generates a copy constructor for a specified `struct` sd if
397  * the following conditions are met:
398  *
399  * 1. sd does not define a copy constructor
400  * 2. at least one field of sd defines a copy constructor
401  *
402  * If the above conditions are met, the following copy constructor
403  * is generated:
404  *
405  * this(ref return scope inout(S) rhs) inout
406  * {
407  *    this.field1 = rhs.field1;
408  *    this.field2 = rhs.field2;
409  *    ...
410  * }
411  *
412  * Params:
413  *  sd = the `struct` for which the copy constructor is generated
414  *  sc = the scope where the copy constructor is generated
415  *
416  * Returns:
417  *  `true` if `struct` sd defines a copy constructor (explicitly or generated),
418  *  `false` otherwise.
419  */
420 private bool buildCopyCtor(StructDeclaration sd, Scope* sc)
421 {
422     if (global.errors)
423         return false;
424 
425     bool hasPostblit;
426     if (sd.postblit && !sd.postblit.isDisabled())
427         hasPostblit = true;
428 
429     auto ctor = sd.search(sd.loc, Id.ctor);
430     CtorDeclaration cpCtor;
431     CtorDeclaration rvalueCtor;
432     if (ctor)
433     {
434         if (ctor.isOverloadSet())
435             return false;
436         if (auto td = ctor.isTemplateDeclaration())
437             ctor = td.funcroot;
438     }
439 
440     if (!ctor)
441         goto LcheckFields;
442 
443     overloadApply(ctor, (Dsymbol s)
444     {
445         if (s.isTemplateDeclaration())
446             return 0;
447         auto ctorDecl = s.isCtorDeclaration();
448         assert(ctorDecl);
449         if (ctorDecl.isCpCtor)
450         {
451             if (!cpCtor)
452                 cpCtor = ctorDecl;
453             return 0;
454         }
455 
456         auto tf = ctorDecl.type.toTypeFunction();
457         const dim = tf.parameterList.length;
458         if (dim == 1)
459         {
460             auto param = tf.parameterList[0];
461             if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
462             {
463                 rvalueCtor = ctorDecl;
464             }
465         }
466         return 0;
467     });
468 
469     if (cpCtor && rvalueCtor)
470     {
471         .error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars());
472         errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
473         errorSupplemental(cpCtor.loc, "copy constructor defined here");
474         return true;
475     }
476     else if (cpCtor)
477     {
478         return !hasPostblit;
479     }
480 
481 LcheckFields:
482     VarDeclaration fieldWithCpCtor;
483     // see if any struct members define a copy constructor
484     foreach (v; sd.fields)
485     {
486         if (v.storage_class & STC.ref_)
487             continue;
488         if (v.overlapped)
489             continue;
490 
491         auto ts = v.type.baseElemOf().isTypeStruct();
492         if (!ts)
493             continue;
494         if (ts.sym.hasCopyCtor)
495         {
496             fieldWithCpCtor = v;
497             break;
498         }
499     }
500 
501     if (fieldWithCpCtor && rvalueCtor)
502     {
503         .error(sd.loc, "`struct %s` may not define a rvalue constructor and have fields with copy constructors", sd.toChars());
504         errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
505         errorSupplemental(fieldWithCpCtor.loc, "field with copy constructor defined here");
506         return false;
507     }
508     else if (!fieldWithCpCtor)
509         return false;
510 
511     if (hasPostblit)
512         return false;
513 
514     //printf("generating copy constructor for %s\n", sd.toChars());
515     const MOD paramMod = MODFlags.wild;
516     const MOD funcMod = MODFlags.wild;
517     auto ccd = generateCopyCtorDeclaration(sd, ModToStc(paramMod), ModToStc(funcMod));
518     auto copyCtorBody = generateCopyCtorBody(sd);
519     ccd.fbody = copyCtorBody;
520     sd.members.push(ccd);
521     ccd.addMember(sc, sd);
522     const errors = global.startGagging();
523     Scope* sc2 = sc.push();
524     sc2.stc = 0;
525     sc2.linkage = LINK.d;
526     ccd.dsymbolSemantic(sc2);
527     ccd.semantic2(sc2);
528     ccd.semantic3(sc2);
529     //printf("ccd semantic: %s\n", ccd.type.toChars());
530     sc2.pop();
531     if (global.endGagging(errors) || sd.isUnionDeclaration())
532     {
533         ccd.storage_class |= STC.disable;
534         ccd.fbody = null;
535     }
536     return true;
537 }
538 
539 private uint setMangleOverride(Dsymbol s, const(char)[] sym)
540 {
541     if (s.isFuncDeclaration() || s.isVarDeclaration())
542     {
543         s.isDeclaration().mangleOverride = sym;
544         return 1;
545     }
546 
547     if (auto ad = s.isAttribDeclaration())
548     {
549         uint nestedCount = 0;
550 
551         ad.include(null).foreachDsymbol( (s) { nestedCount += setMangleOverride(s, sym); } );
552 
553         return nestedCount;
554     }
555     return 0;
556 }
557 
558 /*************************************
559  * Does semantic analysis on the public face of declarations.
560  */
561 extern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc)
562 {
563     scope v = new DsymbolSemanticVisitor(sc);
564     dsym.accept(v);
565 }
566 
567 structalign_t getAlignment(AlignDeclaration ad, Scope* sc)
568 {
569     if (ad.salign != ad.UNKNOWN)
570         return ad.salign;
571 
572     if (!ad.ealign)
573         return ad.salign = STRUCTALIGN_DEFAULT;
574 
575     sc = sc.startCTFE();
576     ad.ealign = ad.ealign.expressionSemantic(sc);
577     ad.ealign = resolveProperties(sc, ad.ealign);
578     sc = sc.endCTFE();
579     ad.ealign = ad.ealign.ctfeInterpret();
580 
581     if (ad.ealign.op == TOK.error)
582         return ad.salign = STRUCTALIGN_DEFAULT;
583 
584     Type tb = ad.ealign.type.toBasetype();
585     auto n = ad.ealign.toInteger();
586 
587     if (n < 1 || n & (n - 1) || structalign_t.max < n || !tb.isintegral())
588     {
589         error(ad.loc, "alignment must be an integer positive power of 2, not %s", ad.ealign.toChars());
590         return ad.salign = STRUCTALIGN_DEFAULT;
591     }
592 
593     return ad.salign = cast(structalign_t)n;
594 }
595 
596 const(char)* getMessage(DeprecatedDeclaration dd)
597 {
598     if (auto sc = dd._scope)
599     {
600         dd._scope = null;
601 
602         sc = sc.startCTFE();
603         dd.msg = dd.msg.expressionSemantic(sc);
604         dd.msg = resolveProperties(sc, dd.msg);
605         sc = sc.endCTFE();
606         dd.msg = dd.msg.ctfeInterpret();
607 
608         if (auto se = dd.msg.toStringExp())
609             dd.msgstr = se.toStringz().ptr;
610         else
611             dd.msg.error("compile time constant expected, not `%s`", dd.msg.toChars());
612     }
613     return dd.msgstr;
614 }
615 
616 
617 // Returns true if a contract can appear without a function body.
618 package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
619 {
620     assert(!funcdecl.fbody);
621 
622     /* Contracts can only appear without a body when they are virtual
623      * interface functions or abstract.
624      */
625     Dsymbol parent = funcdecl.toParent();
626     InterfaceDeclaration id = parent.isInterfaceDeclaration();
627 
628     if (!funcdecl.isAbstract() &&
629         (funcdecl.fensures || funcdecl.frequires) &&
630         !(id && funcdecl.isVirtual()))
631     {
632         auto cd = parent.isClassDeclaration();
633         if (!(cd && cd.isAbstract()))
634             return false;
635     }
636     return true;
637 }
638 
639 private extern(C++) final class DsymbolSemanticVisitor : Visitor
640 {
641     alias visit = Visitor.visit;
642 
643     Scope* sc;
644     this(Scope* sc)
645     {
646         this.sc = sc;
647     }
648 
649     // Save the scope and defer semantic analysis on the Dsymbol.
650     private void deferDsymbolSemantic(Dsymbol s, Scope *scx)
651     {
652         s._scope = scx ? scx : sc.copy();
653         s._scope.setNoFree();
654         Module.addDeferredSemantic(s);
655     }
656 
657     override void visit(Dsymbol dsym)
658     {
659         dsym.error("%p has no semantic routine", dsym);
660     }
661 
662     override void visit(ScopeDsymbol) { }
663     override void visit(Declaration) { }
664 
665     override void visit(AliasThis dsym)
666     {
667         if (dsym.semanticRun != PASS.init)
668             return;
669 
670         if (dsym._scope)
671         {
672             sc = dsym._scope;
673             dsym._scope = null;
674         }
675 
676         if (!sc)
677             return;
678 
679         dsym.semanticRun = PASS.semantic;
680         dsym.isDeprecated_ = !!(sc.stc & STC.deprecated_);
681 
682         Dsymbol p = sc.parent.pastMixin();
683         AggregateDeclaration ad = p.isAggregateDeclaration();
684         if (!ad)
685         {
686             error(dsym.loc, "alias this can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
687             return;
688         }
689 
690         assert(ad.members);
691         Dsymbol s = ad.search(dsym.loc, dsym.ident);
692         if (!s)
693         {
694             s = sc.search(dsym.loc, dsym.ident, null);
695             if (s)
696                 error(dsym.loc, "`%s` is not a member of `%s`", s.toChars(), ad.toChars());
697             else
698                 error(dsym.loc, "undefined identifier `%s`", dsym.ident.toChars());
699             return;
700         }
701         if (ad.aliasthis && s != ad.aliasthis)
702         {
703             error(dsym.loc, "there can be only one alias this");
704             return;
705         }
706 
707         /* disable the alias this conversion so the implicit conversion check
708          * doesn't use it.
709          */
710         ad.aliasthis = null;
711 
712         Dsymbol sx = s;
713         if (sx.isAliasDeclaration())
714             sx = sx.toAlias();
715         Declaration d = sx.isDeclaration();
716         if (d && !d.isTupleDeclaration())
717         {
718             /* https://issues.dlang.org/show_bug.cgi?id=18429
719              *
720              * If the identifier in the AliasThis declaration
721              * is defined later and is a voldemort type, we must
722              * perform semantic on the declaration to deduce the type.
723              */
724             if (!d.type)
725                 d.dsymbolSemantic(sc);
726 
727             Type t = d.type;
728             assert(t);
729             if (ad.type.implicitConvTo(t) > MATCH.nomatch)
730             {
731                 error(dsym.loc, "alias this is not reachable as `%s` already converts to `%s`", ad.toChars(), t.toChars());
732             }
733         }
734 
735         dsym.sym = s;
736         // Restore alias this
737         ad.aliasthis = dsym;
738         dsym.semanticRun = PASS.semanticdone;
739     }
740 
741     override void visit(AliasDeclaration dsym)
742     {
743         if (dsym.semanticRun >= PASS.semanticdone)
744             return;
745         assert(dsym.semanticRun <= PASS.semantic);
746 
747         dsym.storage_class |= sc.stc & STC.deprecated_;
748         dsym.protection = sc.protection;
749         dsym.userAttribDecl = sc.userAttribDecl;
750 
751         if (!sc.func && dsym.inNonRoot())
752             return;
753 
754         aliasSemantic(dsym, sc);
755     }
756 
757     override void visit(VarDeclaration dsym)
758     {
759         version (none)
760         {
761             printf("VarDeclaration::semantic('%s', parent = '%s') sem = %d\n",
762                    dsym.toChars(), sc.parent ? sc.parent.toChars() : null, dsym.semanticRun);
763             printf(" type = %s\n", dsym.type ? dsym.type.toChars() : "null");
764             printf(" stc = x%llx\n", dsym.storage_class);
765             printf(" storage_class = x%llx\n", dsym.storage_class);
766             printf("linkage = %d\n", dsym.linkage);
767             //if (strcmp(toChars(), "mul") == 0) assert(0);
768         }
769         //if (semanticRun > PASS.init)
770         //    return;
771         //semanticRun = PSSsemantic;
772 
773         if (dsym.semanticRun >= PASS.semanticdone)
774             return;
775 
776         if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
777             dsym.overlapped = true;
778 
779         Scope* scx = null;
780         if (dsym._scope)
781         {
782             sc = dsym._scope;
783             scx = sc;
784             dsym._scope = null;
785         }
786 
787         if (!sc)
788             return;
789 
790         dsym.semanticRun = PASS.semantic;
791 
792         /* Pick up storage classes from context, but except synchronized,
793          * override, abstract, and final.
794          */
795         dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));
796         if (dsym.storage_class & STC.extern_ && dsym._init)
797             dsym.error("extern symbols cannot have initializers");
798 
799         dsym.userAttribDecl = sc.userAttribDecl;
800         dsym.cppnamespace = sc.namespace;
801 
802         AggregateDeclaration ad = dsym.isThis();
803         if (ad)
804             dsym.storage_class |= ad.storage_class & STC.TYPECTOR;
805 
806         /* If auto type inference, do the inference
807          */
808         int inferred = 0;
809         if (!dsym.type)
810         {
811             dsym.inuse++;
812 
813             // Infering the type requires running semantic,
814             // so mark the scope as ctfe if required
815             bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
816             if (needctfe)
817             {
818                 sc.flags |= SCOPE.condition;
819                 sc = sc.startCTFE();
820             }
821             //printf("inferring type for %s with init %s\n", dsym.toChars(), dsym._init.toChars());
822             dsym._init = dsym._init.inferType(sc);
823             dsym.type = dsym._init.initializerToExpression().type;
824             if (needctfe)
825                 sc = sc.endCTFE();
826 
827             dsym.inuse--;
828             inferred = 1;
829 
830             /* This is a kludge to support the existing syntax for RAII
831              * declarations.
832              */
833             dsym.storage_class &= ~STC.auto_;
834             dsym.originalType = dsym.type.syntaxCopy();
835         }
836         else
837         {
838             if (!dsym.originalType)
839                 dsym.originalType = dsym.type.syntaxCopy();
840 
841             /* Prefix function attributes of variable declaration can affect
842              * its type:
843              *      pure nothrow void function() fp;
844              *      static assert(is(typeof(fp) == void function() pure nothrow));
845              */
846             Scope* sc2 = sc.push();
847             sc2.stc |= (dsym.storage_class & STC.FUNCATTR);
848             dsym.inuse++;
849             dsym.type = dsym.type.typeSemantic(dsym.loc, sc2);
850             dsym.inuse--;
851             sc2.pop();
852         }
853         //printf(" semantic type = %s\n", dsym.type ? dsym.type.toChars() : "null");
854         if (dsym.type.ty == Terror)
855             dsym.errors = true;
856 
857         dsym.type.checkDeprecated(dsym.loc, sc);
858         dsym.linkage = sc.linkage;
859         dsym.parent = sc.parent;
860         //printf("this = %p, parent = %p, '%s'\n", dsym, dsym.parent, dsym.parent.toChars());
861         dsym.protection = sc.protection;
862 
863         /* If scope's alignment is the default, use the type's alignment,
864          * otherwise the scope overrrides.
865          */
866         dsym.alignment = sc.alignment();
867         if (dsym.alignment == STRUCTALIGN_DEFAULT)
868             dsym.alignment = dsym.type.alignment(); // use type's alignment
869 
870         //printf("sc.stc = %x\n", sc.stc);
871         //printf("storage_class = x%x\n", storage_class);
872 
873         if (global.params.vcomplex)
874             dsym.type.checkComplexTransition(dsym.loc, sc);
875 
876         // Calculate type size + safety checks
877         if (sc.func && !sc.intypeof)
878         {
879             if (dsym.storage_class & STC.gshared && !dsym.isMember())
880             {
881                 if (sc.func.setUnsafe())
882                     dsym.error("__gshared not allowed in safe functions; use shared");
883             }
884         }
885 
886         Dsymbol parent = dsym.toParent();
887 
888         Type tb = dsym.type.toBasetype();
889         Type tbn = tb.baseElemOf();
890         if (tb.ty == Tvoid && !(dsym.storage_class & STC.lazy_))
891         {
892             if (inferred)
893             {
894                 dsym.error("type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", dsym.type.toChars(), dsym._init.toChars());
895             }
896             else
897                 dsym.error("variables cannot be of type `void`");
898             dsym.type = Type.terror;
899             tb = dsym.type;
900         }
901         if (tb.ty == Tfunction)
902         {
903             dsym.error("cannot be declared to be a function");
904             dsym.type = Type.terror;
905             tb = dsym.type;
906         }
907         if (auto ts = tb.isTypeStruct())
908         {
909             if (!ts.sym.members)
910             {
911                 dsym.error("no definition of struct `%s`", ts.toChars());
912             }
913         }
914         if ((dsym.storage_class & STC.auto_) && !inferred)
915             dsym.error("storage class `auto` has no effect if type is not inferred, did you mean `scope`?");
916 
917         if (auto tt = tb.isTypeTuple())
918         {
919             /* Instead, declare variables for each of the tuple elements
920              * and add those.
921              */
922             size_t nelems = Parameter.dim(tt.arguments);
923             Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression() : null;
924             if (ie)
925                 ie = ie.expressionSemantic(sc);
926             if (nelems > 0 && ie)
927             {
928                 auto iexps = new Expressions();
929                 iexps.push(ie);
930                 auto exps = new Expressions();
931                 for (size_t pos = 0; pos < iexps.dim; pos++)
932                 {
933                 Lexpand1:
934                     Expression e = (*iexps)[pos];
935                     Parameter arg = Parameter.getNth(tt.arguments, pos);
936                     arg.type = arg.type.typeSemantic(dsym.loc, sc);
937                     //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
938                     //printf("e = (%s %s, %s), ", Token::tochars[e.op], e.toChars(), e.type.toChars());
939                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
940 
941                     if (e != ie)
942                     {
943                         if (iexps.dim > nelems)
944                             goto Lnomatch;
945                         if (e.type.implicitConvTo(arg.type))
946                             continue;
947                     }
948 
949                     if (e.op == TOK.tuple)
950                     {
951                         TupleExp te = cast(TupleExp)e;
952                         if (iexps.dim - 1 + te.exps.dim > nelems)
953                             goto Lnomatch;
954 
955                         iexps.remove(pos);
956                         iexps.insert(pos, te.exps);
957                         (*iexps)[pos] = Expression.combine(te.e0, (*iexps)[pos]);
958                         goto Lexpand1;
959                     }
960                     else if (isAliasThisTuple(e))
961                     {
962                         auto v = copyToTemp(0, "__tup", e);
963                         v.dsymbolSemantic(sc);
964                         auto ve = new VarExp(dsym.loc, v);
965                         ve.type = e.type;
966 
967                         exps.setDim(1);
968                         (*exps)[0] = ve;
969                         expandAliasThisTuples(exps, 0);
970 
971                         for (size_t u = 0; u < exps.dim; u++)
972                         {
973                         Lexpand2:
974                             Expression ee = (*exps)[u];
975                             arg = Parameter.getNth(tt.arguments, pos + u);
976                             arg.type = arg.type.typeSemantic(dsym.loc, sc);
977                             //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
978                             //printf("ee = (%s %s, %s), ", Token::tochars[ee.op], ee.toChars(), ee.type.toChars());
979                             //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
980 
981                             size_t iexps_dim = iexps.dim - 1 + exps.dim;
982                             if (iexps_dim > nelems)
983                                 goto Lnomatch;
984                             if (ee.type.implicitConvTo(arg.type))
985                                 continue;
986 
987                             if (expandAliasThisTuples(exps, u) != -1)
988                                 goto Lexpand2;
989                         }
990 
991                         if ((*exps)[0] != ve)
992                         {
993                             Expression e0 = (*exps)[0];
994                             (*exps)[0] = new CommaExp(dsym.loc, new DeclarationExp(dsym.loc, v), e0);
995                             (*exps)[0].type = e0.type;
996 
997                             iexps.remove(pos);
998                             iexps.insert(pos, exps);
999                             goto Lexpand1;
1000                         }
1001                     }
1002                 }
1003                 if (iexps.dim < nelems)
1004                     goto Lnomatch;
1005 
1006                 ie = new TupleExp(dsym._init.loc, iexps);
1007             }
1008         Lnomatch:
1009 
1010             if (ie && ie.op == TOK.tuple)
1011             {
1012                 TupleExp te = cast(TupleExp)ie;
1013                 size_t tedim = te.exps.dim;
1014                 if (tedim != nelems)
1015                 {
1016                     error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
1017                     for (size_t u = tedim; u < nelems; u++) // fill dummy expression
1018                         te.exps.push(ErrorExp.get());
1019                 }
1020             }
1021 
1022             auto exps = new Objects(nelems);
1023             for (size_t i = 0; i < nelems; i++)
1024             {
1025                 Parameter arg = Parameter.getNth(tt.arguments, i);
1026 
1027                 OutBuffer buf;
1028                 buf.printf("__%s_field_%llu", dsym.ident.toChars(), cast(ulong)i);
1029                 auto id = Identifier.idPool(buf[]);
1030 
1031                 Initializer ti;
1032                 if (ie)
1033                 {
1034                     Expression einit = ie;
1035                     if (ie.op == TOK.tuple)
1036                     {
1037                         TupleExp te = cast(TupleExp)ie;
1038                         einit = (*te.exps)[i];
1039                         if (i == 0)
1040                             einit = Expression.combine(te.e0, einit);
1041                     }
1042                     ti = new ExpInitializer(einit.loc, einit);
1043                 }
1044                 else
1045                     ti = dsym._init ? dsym._init.syntaxCopy() : null;
1046 
1047                 StorageClass storage_class = STC.temp | dsym.storage_class;
1048                 if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter))
1049                     storage_class |= arg.storageClass;
1050                 auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);
1051                 //printf("declaring field %s of type %s\n", v.toChars(), v.type.toChars());
1052                 v.dsymbolSemantic(sc);
1053 
1054                 if (sc.scopesym)
1055                 {
1056                     //printf("adding %s to %s\n", v.toChars(), sc.scopesym.toChars());
1057                     if (sc.scopesym.members)
1058                         // Note this prevents using foreach() over members, because the limits can change
1059                         sc.scopesym.members.push(v);
1060                 }
1061 
1062                 Expression e = new DsymbolExp(dsym.loc, v);
1063                 (*exps)[i] = e;
1064             }
1065             auto v2 = new TupleDeclaration(dsym.loc, dsym.ident, exps);
1066             v2.parent = dsym.parent;
1067             v2.isexp = true;
1068             dsym.aliassym = v2;
1069             dsym.semanticRun = PASS.semanticdone;
1070             return;
1071         }
1072 
1073         /* Storage class can modify the type
1074          */
1075         dsym.type = dsym.type.addStorageClass(dsym.storage_class);
1076 
1077         /* Adjust storage class to reflect type
1078          */
1079         if (dsym.type.isConst())
1080         {
1081             dsym.storage_class |= STC.const_;
1082             if (dsym.type.isShared())
1083                 dsym.storage_class |= STC.shared_;
1084         }
1085         else if (dsym.type.isImmutable())
1086             dsym.storage_class |= STC.immutable_;
1087         else if (dsym.type.isShared())
1088             dsym.storage_class |= STC.shared_;
1089         else if (dsym.type.isWild())
1090             dsym.storage_class |= STC.wild;
1091 
1092         if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_))
1093         {
1094             if (stc == STC.final_)
1095                 dsym.error("cannot be `final`, perhaps you meant `const`?");
1096             else
1097             {
1098                 OutBuffer buf;
1099                 stcToBuffer(&buf, stc);
1100                 dsym.error("cannot be `%s`", buf.peekChars());
1101             }
1102             dsym.storage_class &= ~stc; // strip off
1103         }
1104 
1105         // At this point we can add `scope` to the STC instead of `in`,
1106         // because we are never going to use this variable's STC for user messages
1107         if (dsym.storage_class & STC.in_ && global.params.previewIn)
1108             dsym.storage_class |= STC.scope_;
1109 
1110         if (dsym.storage_class & STC.scope_)
1111         {
1112             StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.tls | STC.gshared);
1113             if (stc)
1114             {
1115                 OutBuffer buf;
1116                 stcToBuffer(&buf, stc);
1117                 dsym.error("cannot be `scope` and `%s`", buf.peekChars());
1118             }
1119             else if (dsym.isMember())
1120             {
1121                 dsym.error("field cannot be `scope`");
1122             }
1123             else if (!dsym.type.hasPointers())
1124             {
1125                 dsym.storage_class &= ~STC.scope_;     // silently ignore; may occur in generic code
1126             }
1127         }
1128 
1129         if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.tls | STC.gshared | STC.ctfe))
1130         {
1131         }
1132         else
1133         {
1134             AggregateDeclaration aad = parent.isAggregateDeclaration();
1135             if (aad)
1136             {
1137                 if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer())
1138                 {
1139                     const(char)* s = (dsym.storage_class & STC.immutable_) ? "immutable" : "const";
1140                     message(dsym.loc, "`%s.%s` is `%s` field", ad.toPrettyChars(), dsym.toChars(), s);
1141                 }
1142                 dsym.storage_class |= STC.field;
1143                 if (auto ts = tbn.isTypeStruct())
1144                     if (ts.sym.noDefaultCtor)
1145                     {
1146                         if (!dsym.isThisDeclaration() && !dsym._init)
1147                             aad.noDefaultCtor = true;
1148                     }
1149             }
1150 
1151             InterfaceDeclaration id = parent.isInterfaceDeclaration();
1152             if (id)
1153             {
1154                 dsym.error("field not allowed in interface");
1155             }
1156             else if (aad && aad.sizeok == Sizeok.done)
1157             {
1158                 dsym.error("cannot be further field because it will change the determined %s size", aad.toChars());
1159             }
1160 
1161             /* Templates cannot add fields to aggregates
1162              */
1163             TemplateInstance ti = parent.isTemplateInstance();
1164             if (ti)
1165             {
1166                 // Take care of nested templates
1167                 while (1)
1168                 {
1169                     TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
1170                     if (!ti2)
1171                         break;
1172                     ti = ti2;
1173                 }
1174                 // If it's a member template
1175                 AggregateDeclaration ad2 = ti.tempdecl.isMember();
1176                 if (ad2 && dsym.storage_class != STC.undefined_)
1177                 {
1178                     dsym.error("cannot use template to add field to aggregate `%s`", ad2.toChars());
1179                 }
1180             }
1181         }
1182 
1183         if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)
1184         {
1185             dsym.error("only parameters or `foreach` declarations can be `ref`");
1186         }
1187 
1188         if (dsym.type.hasWild())
1189         {
1190             if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg())
1191             {
1192                 dsym.error("only parameters or stack based variables can be `inout`");
1193             }
1194             FuncDeclaration func = sc.func;
1195             if (func)
1196             {
1197                 if (func.fes)
1198                     func = func.fes.func;
1199                 bool isWild = false;
1200                 for (FuncDeclaration fd = func; fd; fd = fd.toParentDecl().isFuncDeclaration())
1201                 {
1202                     if ((cast(TypeFunction)fd.type).iswild)
1203                     {
1204                         isWild = true;
1205                         break;
1206                     }
1207                 }
1208                 if (!isWild)
1209                 {
1210                     dsym.error("`inout` variables can only be declared inside `inout` functions");
1211                 }
1212             }
1213         }
1214 
1215         if (!(dsym.storage_class & (STC.ctfe | STC.ref_ | STC.result)) &&
1216             tbn.ty == Tstruct && (cast(TypeStruct)tbn).sym.noDefaultCtor)
1217         {
1218             if (!dsym._init)
1219             {
1220                 if (dsym.isField())
1221                 {
1222                     /* For fields, we'll check the constructor later to make sure it is initialized
1223                      */
1224                     dsym.storage_class |= STC.nodefaultctor;
1225                 }
1226                 else if (dsym.storage_class & STC.parameter)
1227                 {
1228                 }
1229                 else
1230                     dsym.error("default construction is disabled for type `%s`", dsym.type.toChars());
1231             }
1232         }
1233 
1234         FuncDeclaration fd = parent.isFuncDeclaration();
1235         if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor))
1236         {
1237             if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.tls | STC.gshared) || !fd)
1238             {
1239                 dsym.error("globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`");
1240             }
1241 
1242             // @@@DEPRECATED@@@  https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
1243             // Deprecated in 2.087
1244             // Remove this when the feature is removed from the language
1245             if (0 &&          // deprecation disabled for now to accommodate existing extensive use
1246                !(dsym.storage_class & STC.scope_))
1247             {
1248                 if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym)
1249                     dsym.error("reference to `scope class` must be `scope`");
1250             }
1251         }
1252 
1253         // Calculate type size + safety checks
1254         if (sc.func && !sc.intypeof)
1255         {
1256             if (dsym._init && dsym._init.isVoidInitializer() && dsym.type.hasPointers()) // get type size
1257             {
1258                 if (sc.func.setUnsafe())
1259                     dsym.error("`void` initializers for pointers not allowed in safe functions");
1260             }
1261             else if (!dsym._init &&
1262                      !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&
1263                      dsym.type.hasVoidInitPointers())
1264             {
1265                 if (sc.func.setUnsafe())
1266                     dsym.error("`void` initializers for pointers not allowed in safe functions");
1267             }
1268         }
1269 
1270         if ((!dsym._init || dsym._init.isVoidInitializer) && !fd)
1271         {
1272             // If not mutable, initializable by constructor only
1273             dsym.storage_class |= STC.ctorinit;
1274         }
1275 
1276         if (dsym._init)
1277             dsym.storage_class |= STC.init; // remember we had an explicit initializer
1278         else if (dsym.storage_class & STC.manifest)
1279             dsym.error("manifest constants must have initializers");
1280 
1281         bool isBlit = false;
1282         d_uns64 sz;
1283         if (!dsym._init &&
1284             !(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&
1285             fd &&
1286             (!(dsym.storage_class & (STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result)) ||
1287              (dsym.storage_class & STC.out_)) &&
1288             (sz = dsym.type.size()) != 0)
1289         {
1290             // Provide a default initializer
1291 
1292             //printf("Providing default initializer for '%s'\n", toChars());
1293             if (sz == SIZE_INVALID && dsym.type.ty != Terror)
1294                 dsym.error("size of type `%s` is invalid", dsym.type.toChars());
1295 
1296             Type tv = dsym.type;
1297             while (tv.ty == Tsarray)    // Don't skip Tenum
1298                 tv = tv.nextOf();
1299             if (tv.needsNested())
1300             {
1301                 /* Nested struct requires valid enclosing frame pointer.
1302                  * In StructLiteralExp::toElem(), it's calculated.
1303                  */
1304                 assert(tbn.ty == Tstruct);
1305                 checkFrameAccess(dsym.loc, sc, tbn.isTypeStruct().sym);
1306 
1307                 Expression e = tv.defaultInitLiteral(dsym.loc);
1308                 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
1309                 e = e.expressionSemantic(sc);
1310                 dsym._init = new ExpInitializer(dsym.loc, e);
1311                 goto Ldtor;
1312             }
1313             if (tv.ty == Tstruct && (cast(TypeStruct)tv).sym.zeroInit)
1314             {
1315                 /* If a struct is all zeros, as a special case
1316                  * set it's initializer to the integer 0.
1317                  * In AssignExp::toElem(), we check for this and issue
1318                  * a memset() to initialize the struct.
1319                  * Must do same check in interpreter.
1320                  */
1321                 Expression e = IntegerExp.literal!0;
1322                 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
1323                 e.type = dsym.type;      // don't type check this, it would fail
1324                 dsym._init = new ExpInitializer(dsym.loc, e);
1325                 goto Ldtor;
1326             }
1327             if (dsym.type.baseElemOf().ty == Tvoid)
1328             {
1329                 dsym.error("`%s` does not have a default initializer", dsym.type.toChars());
1330             }
1331             else if (auto e = dsym.type.defaultInit(dsym.loc))
1332             {
1333                 dsym._init = new ExpInitializer(dsym.loc, e);
1334             }
1335 
1336             // Default initializer is always a blit
1337             isBlit = true;
1338         }
1339         if (dsym._init)
1340         {
1341             sc = sc.push();
1342             sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);
1343 
1344             ExpInitializer ei = dsym._init.isExpInitializer();
1345             if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424
1346                     // Preset the required type to fail in FuncLiteralDeclaration::semantic3
1347                 ei.exp = inferType(ei.exp, dsym.type);
1348 
1349             // If inside function, there is no semantic3() call
1350             if (sc.func || sc.intypeof == 1)
1351             {
1352                 // If local variable, use AssignExp to handle all the various
1353                 // possibilities.
1354                 if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.tls | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())
1355                 {
1356                     //printf("fd = '%s', var = '%s'\n", fd.toChars(), toChars());
1357                     if (!ei)
1358                     {
1359                         ArrayInitializer ai = dsym._init.isArrayInitializer();
1360                         Expression e;
1361                         if (ai && tb.ty == Taarray)
1362                             e = ai.toAssocArrayLiteral();
1363                         else
1364                             e = dsym._init.initializerToExpression();
1365                         if (!e)
1366                         {
1367                             // Run semantic, but don't need to interpret
1368                             dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret);
1369                             e = dsym._init.initializerToExpression();
1370                             if (!e)
1371                             {
1372                                 dsym.error("is not a static and cannot have static initializer");
1373                                 e = ErrorExp.get();
1374                             }
1375                         }
1376                         ei = new ExpInitializer(dsym._init.loc, e);
1377                         dsym._init = ei;
1378                     }
1379 
1380                     Expression exp = ei.exp;
1381                     Expression e1 = new VarExp(dsym.loc, dsym);
1382                     if (isBlit)
1383                         exp = new BlitExp(dsym.loc, e1, exp);
1384                     else
1385                         exp = new ConstructExp(dsym.loc, e1, exp);
1386                     dsym.canassign++;
1387                     exp = exp.expressionSemantic(sc);
1388                     dsym.canassign--;
1389                     exp = exp.optimize(WANTvalue);
1390                     if (exp.op == TOK.error)
1391                     {
1392                         dsym._init = new ErrorInitializer();
1393                         ei = null;
1394                     }
1395                     else
1396                         ei.exp = exp;
1397 
1398                     if (ei && dsym.isScope())
1399                     {
1400                         Expression ex = ei.exp.lastComma();
1401                         if (ex.op == TOK.blit || ex.op == TOK.construct)
1402                             ex = (cast(AssignExp)ex).e2;
1403                         if (ex.op == TOK.new_)
1404                         {
1405                             // See if initializer is a NewExp that can be allocated on the stack
1406                             NewExp ne = cast(NewExp)ex;
1407                             if (dsym.type.toBasetype().ty == Tclass)
1408                             {
1409                                 if (ne.newargs && ne.newargs.dim > 1)
1410                                 {
1411                                     dsym.mynew = true;
1412                                 }
1413                                 else
1414                                 {
1415                                     ne.onstack = 1;
1416                                     dsym.onstack = true;
1417                                 }
1418                             }
1419                         }
1420                         else if (ex.op == TOK.function_)
1421                         {
1422                             // or a delegate that doesn't escape a reference to the function
1423                             FuncDeclaration f = (cast(FuncExp)ex).fd;
1424                             if (f.tookAddressOf)
1425                                 f.tookAddressOf--;
1426                         }
1427                     }
1428                 }
1429                 else
1430                 {
1431                     // https://issues.dlang.org/show_bug.cgi?id=14166
1432                     // Don't run CTFE for the temporary variables inside typeof
1433                     dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);
1434                     const init_err = dsym._init.isExpInitializer();
1435                     if (init_err && init_err.exp.op == TOK.showCtfeContext)
1436                     {
1437                          errorSupplemental(dsym.loc, "compile time context created here");
1438                     }
1439                 }
1440             }
1441             else if (parent.isAggregateDeclaration())
1442             {
1443                 dsym._scope = scx ? scx : sc.copy();
1444                 dsym._scope.setNoFree();
1445             }
1446             else if (dsym.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) || dsym.type.isConst() || dsym.type.isImmutable())
1447             {
1448                 /* Because we may need the results of a const declaration in a
1449                  * subsequent type, such as an array dimension, before semantic2()
1450                  * gets ordinarily run, try to run semantic2() now.
1451                  * Ignore failure.
1452                  */
1453                 if (!inferred)
1454                 {
1455                     uint errors = global.errors;
1456                     dsym.inuse++;
1457                     // Bug 20549. Don't try this on modules or packages, syntaxCopy
1458                     // could crash (inf. recursion) on a mod/pkg referencing itself
1459                     if (ei && (ei.exp.op != TOK.scope_ ? true : !(cast(ScopeExp)ei.exp).sds.isPackage()))
1460                     {
1461                         Expression exp = ei.exp.syntaxCopy();
1462 
1463                         bool needctfe = dsym.isDataseg() || (dsym.storage_class & STC.manifest);
1464                         if (needctfe)
1465                             sc = sc.startCTFE();
1466                         exp = exp.expressionSemantic(sc);
1467                         exp = resolveProperties(sc, exp);
1468                         if (needctfe)
1469                             sc = sc.endCTFE();
1470 
1471                         Type tb2 = dsym.type.toBasetype();
1472                         Type ti = exp.type.toBasetype();
1473 
1474                         /* The problem is the following code:
1475                          *  struct CopyTest {
1476                          *     double x;
1477                          *     this(double a) { x = a * 10.0;}
1478                          *     this(this) { x += 2.0; }
1479                          *  }
1480                          *  const CopyTest z = CopyTest(5.3);  // ok
1481                          *  const CopyTest w = z;              // not ok, postblit not run
1482                          *  static assert(w.x == 55.0);
1483                          * because the postblit doesn't get run on the initialization of w.
1484                          */
1485                         if (auto ts = ti.isTypeStruct())
1486                         {
1487                             StructDeclaration sd = ts.sym;
1488                             /* Look to see if initializer involves a copy constructor
1489                              * (which implies a postblit)
1490                              */
1491                             // there is a copy constructor
1492                             // and exp is the same struct
1493                             if (sd.postblit && tb2.toDsymbol(null) == sd)
1494                             {
1495                                 // The only allowable initializer is a (non-copy) constructor
1496                                 if (exp.isLvalue())
1497                                     dsym.error("of type struct `%s` uses `this(this)`, which is not allowed in static initialization", tb2.toChars());
1498                             }
1499                         }
1500                         ei.exp = exp;
1501                     }
1502                     dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
1503                     dsym.inuse--;
1504                     if (global.errors > errors)
1505                     {
1506                         dsym._init = new ErrorInitializer();
1507                         dsym.type = Type.terror;
1508                     }
1509                 }
1510                 else
1511                 {
1512                     dsym._scope = scx ? scx : sc.copy();
1513                     dsym._scope.setNoFree();
1514                 }
1515             }
1516             sc = sc.pop();
1517         }
1518 
1519     Ldtor:
1520         /* Build code to execute destruction, if necessary
1521          */
1522         dsym.edtor = dsym.callScopeDtor(sc);
1523         if (dsym.edtor)
1524         {
1525             /* If dsym is a local variable, who's type is a struct with a scope destructor,
1526              * then make dsym scope, too.
1527              */
1528             if (global.params.vsafe &&
1529                 !(dsym.storage_class & (STC.parameter | STC.temp | STC.field | STC.in_ | STC.foreach_ | STC.result | STC.manifest)) &&
1530                 !dsym.isDataseg() &&
1531                 !dsym.doNotInferScope &&
1532                 dsym.type.hasPointers())
1533             {
1534                 auto tv = dsym.type.baseElemOf();
1535                 if (tv.ty == Tstruct &&
1536                     (cast(TypeStruct)tv).sym.dtor.storage_class & STC.scope_)
1537                 {
1538                     dsym.storage_class |= STC.scope_;
1539                 }
1540             }
1541 
1542             if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared))
1543                 dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope);
1544             else
1545                 dsym.edtor = dsym.edtor.expressionSemantic(sc);
1546 
1547             version (none)
1548             {
1549                 // currently disabled because of std.stdio.stdin, stdout and stderr
1550                 if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_))
1551                     dsym.error("static storage variables cannot have destructors");
1552             }
1553         }
1554 
1555         dsym.semanticRun = PASS.semanticdone;
1556 
1557         if (dsym.type.toBasetype().ty == Terror)
1558             dsym.errors = true;
1559 
1560         if(sc.scopesym && !sc.scopesym.isAggregateDeclaration())
1561         {
1562             for (ScopeDsymbol sym = sc.scopesym; sym && dsym.endlinnum == 0;
1563                  sym = sym.parent ? sym.parent.isScopeDsymbol() : null)
1564                 dsym.endlinnum = sym.endlinnum;
1565         }
1566     }
1567 
1568     override void visit(TypeInfoDeclaration dsym)
1569     {
1570         assert(dsym.linkage == LINK.c);
1571     }
1572 
1573     override void visit(Import imp)
1574     {
1575         //printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
1576         if (imp.semanticRun > PASS.init)
1577             return;
1578 
1579         if (imp._scope)
1580         {
1581             sc = imp._scope;
1582             imp._scope = null;
1583         }
1584         if (!sc)
1585             return;
1586 
1587         imp.semanticRun = PASS.semantic;
1588 
1589         // Load if not already done so
1590         bool loadErrored = false;
1591         if (!imp.mod)
1592         {
1593             loadErrored = imp.load(sc);
1594             if (imp.mod)
1595             {
1596                 imp.mod.importAll(null);
1597                 imp.mod.checkImportDeprecation(imp.loc, sc);
1598             }
1599         }
1600         if (imp.mod)
1601         {
1602             // Modules need a list of each imported module
1603 
1604             // if inside a template instantiation, the instantianting
1605             // module gets the import.
1606             // https://issues.dlang.org/show_bug.cgi?id=17181
1607             Module importer = sc._module;
1608             if (sc.minst && sc.tinst)
1609             {
1610                 importer = sc.minst;
1611                 if (!sc.tinst.importedModules.contains(imp.mod))
1612                     sc.tinst.importedModules.push(imp.mod);
1613             }
1614             //printf("%s imports %s\n", importer.toChars(), imp.mod.toChars());
1615             if (!importer.aimports.contains(imp.mod))
1616                 importer.aimports.push(imp.mod);
1617 
1618             if (sc.explicitProtection)
1619                 imp.protection = sc.protection;
1620 
1621             if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import
1622             {
1623                 ScopeDsymbol scopesym;
1624                 for (Scope* scd = sc; scd; scd = scd.enclosing)
1625                 {
1626                     if (!scd.scopesym)
1627                         continue;
1628                     scopesym = scd.scopesym;
1629                     break;
1630                 }
1631 
1632                 if (!imp.isstatic)
1633                 {
1634                     scopesym.importScope(imp.mod, imp.protection);
1635                 }
1636 
1637                 // Mark the imported packages as accessible from the current
1638                 // scope. This access check is necessary when using FQN b/c
1639                 // we're using a single global package tree.
1640                 // https://issues.dlang.org/show_bug.cgi?id=313
1641                 if (imp.packages)
1642                 {
1643                     // import a.b.c.d;
1644                     auto p = imp.pkg; // a
1645                     scopesym.addAccessiblePackage(p, imp.protection);
1646                     foreach (id; (*imp.packages)[1 .. imp.packages.dim]) // [b, c]
1647                     {
1648                         p = cast(Package) p.symtab.lookup(id);
1649                         // https://issues.dlang.org/show_bug.cgi?id=17991
1650                         // An import of truly empty file/package can happen
1651                         // https://issues.dlang.org/show_bug.cgi?id=20151
1652                         // Package in the path conflicts with a module name
1653                         if (p is null)
1654                             break;
1655                         scopesym.addAccessiblePackage(p, imp.protection);
1656                     }
1657                 }
1658                 scopesym.addAccessiblePackage(imp.mod, imp.protection); // d
1659             }
1660 
1661             if (!loadErrored)
1662             {
1663                 imp.mod.dsymbolSemantic(null);
1664             }
1665 
1666             if (imp.mod.needmoduleinfo)
1667             {
1668                 //printf("module4 %s because of %s\n", importer.toChars(), imp.mod.toChars());
1669                 importer.needmoduleinfo = 1;
1670             }
1671 
1672             sc = sc.push(imp.mod);
1673             sc.protection = imp.protection;
1674             for (size_t i = 0; i < imp.aliasdecls.dim; i++)
1675             {
1676                 AliasDeclaration ad = imp.aliasdecls[i];
1677                 //printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
1678                 Dsymbol sym = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);
1679                 if (sym)
1680                 {
1681                     import dmd.access : symbolIsVisible;
1682                     if (!symbolIsVisible(sc, sym))
1683                         imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`",
1684                             imp.names[i].toChars(), sc._module.toChars());
1685                     ad.dsymbolSemantic(sc);
1686                     // If the import declaration is in non-root module,
1687                     // analysis of the aliased symbol is deferred.
1688                     // Therefore, don't see the ad.aliassym or ad.type here.
1689                 }
1690                 else
1691                 {
1692                     Dsymbol s = imp.mod.search_correct(imp.names[i]);
1693                     if (s)
1694                         imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
1695                     else
1696                         imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
1697                     ad.type = Type.terror;
1698                 }
1699             }
1700             sc = sc.pop();
1701         }
1702 
1703         imp.semanticRun = PASS.semanticdone;
1704 
1705         // object self-imports itself, so skip that
1706         // https://issues.dlang.org/show_bug.cgi?id=7547
1707         // don't list pseudo modules __entrypoint.d, __main.d
1708         // https://issues.dlang.org/show_bug.cgi?id=11117
1709         // https://issues.dlang.org/show_bug.cgi?id=11164
1710         if (global.params.moduleDeps !is null && !(imp.id == Id.object && sc._module.ident == Id.object) &&
1711             strcmp(sc._module.ident.toChars(), "__main") != 0)
1712         {
1713             /* The grammar of the file is:
1714              *      ImportDeclaration
1715              *          ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
1716              *      ModuleAliasIdentifier ] "\n"
1717              *
1718              *      BasicImportDeclaration
1719              *          ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
1720              *              " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
1721              *
1722              *      FilePath
1723              *          - any string with '(', ')' and '\' escaped with the '\' character
1724              */
1725             OutBuffer* ob = global.params.moduleDeps;
1726             Module imod = sc.instantiatingModule();
1727             if (!global.params.moduleDepsFile)
1728                 ob.writestring("depsImport ");
1729             ob.writestring(imod.toPrettyChars());
1730             ob.writestring(" (");
1731             escapePath(ob, imod.srcfile.toChars());
1732             ob.writestring(") : ");
1733             // use protection instead of sc.protection because it couldn't be
1734             // resolved yet, see the comment above
1735             protectionToBuffer(ob, imp.protection);
1736             ob.writeByte(' ');
1737             if (imp.isstatic)
1738             {
1739                 stcToBuffer(ob, STC.static_);
1740                 ob.writeByte(' ');
1741             }
1742             ob.writestring(": ");
1743             if (imp.packages)
1744             {
1745                 for (size_t i = 0; i < imp.packages.dim; i++)
1746                 {
1747                     Identifier pid = (*imp.packages)[i];
1748                     ob.printf("%s.", pid.toChars());
1749                 }
1750             }
1751             ob.writestring(imp.id.toString());
1752             ob.writestring(" (");
1753             if (imp.mod)
1754                 escapePath(ob, imp.mod.srcfile.toChars());
1755             else
1756                 ob.writestring("???");
1757             ob.writeByte(')');
1758             foreach (i, name; imp.names)
1759             {
1760                 if (i == 0)
1761                     ob.writeByte(':');
1762                 else
1763                     ob.writeByte(',');
1764                 Identifier _alias = imp.aliases[i];
1765                 if (!_alias)
1766                 {
1767                     ob.printf("%s", name.toChars());
1768                     _alias = name;
1769                 }
1770                 else
1771                     ob.printf("%s=%s", _alias.toChars(), name.toChars());
1772             }
1773             if (imp.aliasId)
1774                 ob.printf(" -> %s", imp.aliasId.toChars());
1775             ob.writenl();
1776         }
1777         //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
1778     }
1779 
1780     void attribSemantic(AttribDeclaration ad)
1781     {
1782         if (ad.semanticRun != PASS.init)
1783             return;
1784         ad.semanticRun = PASS.semantic;
1785         Dsymbols* d = ad.include(sc);
1786         //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
1787         if (d)
1788         {
1789             Scope* sc2 = ad.newScope(sc);
1790             bool errors;
1791             for (size_t i = 0; i < d.dim; i++)
1792             {
1793                 Dsymbol s = (*d)[i];
1794                 s.dsymbolSemantic(sc2);
1795                 errors |= s.errors;
1796             }
1797             ad.errors |= errors;
1798             if (sc2 != sc)
1799                 sc2.pop();
1800         }
1801         ad.semanticRun = PASS.semanticdone;
1802     }
1803 
1804     override void visit(AttribDeclaration atd)
1805     {
1806         attribSemantic(atd);
1807     }
1808 
1809     override void visit(AnonDeclaration scd)
1810     {
1811         //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
1812         assert(sc.parent);
1813         auto p = sc.parent.pastMixin();
1814         auto ad = p.isAggregateDeclaration();
1815         if (!ad)
1816         {
1817             error(scd.loc, "%s can only be a part of an aggregate, not %s `%s`", scd.kind(), p.kind(), p.toChars());
1818             scd.errors = true;
1819             return;
1820         }
1821 
1822         if (scd.decl)
1823         {
1824             sc = sc.push();
1825             sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.gshared);
1826             sc.inunion = scd.isunion ? scd : null;
1827             sc.flags = 0;
1828             for (size_t i = 0; i < scd.decl.dim; i++)
1829             {
1830                 Dsymbol s = (*scd.decl)[i];
1831                 s.dsymbolSemantic(sc);
1832             }
1833             sc = sc.pop();
1834         }
1835     }
1836 
1837     override void visit(PragmaDeclaration pd)
1838     {
1839         // Should be merged with PragmaStatement
1840         //printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
1841         if (global.params.mscoff)
1842         {
1843             if (pd.ident == Id.linkerDirective)
1844             {
1845                 if (!pd.args || pd.args.dim != 1)
1846                     pd.error("one string argument expected for pragma(linkerDirective)");
1847                 else
1848                 {
1849                     auto se = semanticString(sc, (*pd.args)[0], "linker directive");
1850                     if (!se)
1851                         goto Lnodecl;
1852                     (*pd.args)[0] = se;
1853                     if (global.params.verbose)
1854                         message("linkopt   %.*s", cast(int)se.len, se.peekString().ptr);
1855                 }
1856                 goto Lnodecl;
1857             }
1858         }
1859         if (pd.ident == Id.msg)
1860         {
1861             if (pd.args)
1862             {
1863                 for (size_t i = 0; i < pd.args.dim; i++)
1864                 {
1865                     Expression e = (*pd.args)[i];
1866                     sc = sc.startCTFE();
1867                     e = e.expressionSemantic(sc);
1868                     e = resolveProperties(sc, e);
1869                     sc = sc.endCTFE();
1870                     // pragma(msg) is allowed to contain types as well as expressions
1871                     if (e.type && e.type.ty == Tvoid)
1872                     {
1873                         error(pd.loc, "Cannot pass argument `%s` to `pragma msg` because it is `void`", e.toChars());
1874                         return;
1875                     }
1876                     e = ctfeInterpretForPragmaMsg(e);
1877                     if (e.op == TOK.error)
1878                     {
1879                         errorSupplemental(pd.loc, "while evaluating `pragma(msg, %s)`", (*pd.args)[i].toChars());
1880                         return;
1881                     }
1882                     StringExp se = e.toStringExp();
1883                     if (se)
1884                     {
1885                         se = se.toUTF8(sc);
1886                         fprintf(stderr, "%.*s", cast(int)se.len, se.peekString().ptr);
1887                     }
1888                     else
1889                         fprintf(stderr, "%s", e.toChars());
1890                 }
1891                 fprintf(stderr, "\n");
1892             }
1893             goto Lnodecl;
1894         }
1895         else if (pd.ident == Id.lib)
1896         {
1897             if (!pd.args || pd.args.dim != 1)
1898                 pd.error("string expected for library name");
1899             else
1900             {
1901                 auto se = semanticString(sc, (*pd.args)[0], "library name");
1902                 if (!se)
1903                     goto Lnodecl;
1904                 (*pd.args)[0] = se;
1905 
1906                 auto name = se.peekString().xarraydup;
1907                 if (global.params.verbose)
1908                     message("library   %s", name.ptr);
1909                 if (global.params.moduleDeps && !global.params.moduleDepsFile)
1910                 {
1911                     OutBuffer* ob = global.params.moduleDeps;
1912                     Module imod = sc.instantiatingModule();
1913                     ob.writestring("depsLib ");
1914                     ob.writestring(imod.toPrettyChars());
1915                     ob.writestring(" (");
1916                     escapePath(ob, imod.srcfile.toChars());
1917                     ob.writestring(") : ");
1918                     ob.writestring(name);
1919                     ob.writenl();
1920                 }
1921                 mem.xfree(name.ptr);
1922             }
1923             goto Lnodecl;
1924         }
1925         else if (pd.ident == Id.startaddress)
1926         {
1927             if (!pd.args || pd.args.dim != 1)
1928                 pd.error("function name expected for start address");
1929             else
1930             {
1931                 /* https://issues.dlang.org/show_bug.cgi?id=11980
1932                  * resolveProperties and ctfeInterpret call are not necessary.
1933                  */
1934                 Expression e = (*pd.args)[0];
1935                 sc = sc.startCTFE();
1936                 e = e.expressionSemantic(sc);
1937                 sc = sc.endCTFE();
1938                 (*pd.args)[0] = e;
1939                 Dsymbol sa = getDsymbol(e);
1940                 if (!sa || !sa.isFuncDeclaration())
1941                     pd.error("function name expected for start address, not `%s`", e.toChars());
1942             }
1943             goto Lnodecl;
1944         }
1945         else if (pd.ident == Id.Pinline)
1946         {
1947             goto Ldecl;
1948         }
1949         else if (pd.ident == Id.mangle)
1950         {
1951             if (!pd.args)
1952                 pd.args = new Expressions();
1953             if (pd.args.dim != 1)
1954             {
1955                 pd.error("string expected for mangled name");
1956                 pd.args.setDim(1);
1957                 (*pd.args)[0] = ErrorExp.get(); // error recovery
1958                 goto Ldecl;
1959             }
1960 
1961             auto se = semanticString(sc, (*pd.args)[0], "mangled name");
1962             if (!se)
1963                 goto Ldecl;
1964             (*pd.args)[0] = se; // Will be used later
1965 
1966             if (!se.len)
1967             {
1968                 pd.error("zero-length string not allowed for mangled name");
1969                 goto Ldecl;
1970             }
1971             if (se.sz != 1)
1972             {
1973                 pd.error("mangled name characters can only be of type `char`");
1974                 goto Ldecl;
1975             }
1976             version (all)
1977             {
1978                 /* Note: D language specification should not have any assumption about backend
1979                  * implementation. Ideally pragma(mangle) can accept a string of any content.
1980                  *
1981                  * Therefore, this validation is compiler implementation specific.
1982                  */
1983                 auto slice = se.peekString();
1984                 for (size_t i = 0; i < se.len;)
1985                 {
1986                     dchar c = slice[i];
1987                     if (c < 0x80)
1988                     {
1989                         if (c.isValidMangling)
1990                         {
1991                             ++i;
1992                             continue;
1993                         }
1994                         else
1995                         {
1996                             pd.error("char 0x%02x not allowed in mangled name", c);
1997                             break;
1998                         }
1999                     }
2000                     if (const msg = utf_decodeChar(slice, i, c))
2001                     {
2002                         pd.error("%.*s", cast(int)msg.length, msg.ptr);
2003                         break;
2004                     }
2005                     if (!isUniAlpha(c))
2006                     {
2007                         pd.error("char `0x%04x` not allowed in mangled name", c);
2008                         break;
2009                     }
2010                 }
2011             }
2012         }
2013         else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
2014         {
2015             if (pd.args && pd.args.dim != 0)
2016                 pd.error("takes no argument");
2017             goto Ldecl;
2018         }
2019         else if (pd.ident == Id.printf || pd.ident == Id.scanf)
2020         {
2021             if (pd.args && pd.args.dim != 0)
2022                 pd.error("takes no argument");
2023             goto Ldecl;
2024         }
2025         else if (global.params.ignoreUnsupportedPragmas)
2026         {
2027             if (global.params.verbose)
2028             {
2029                 /* Print unrecognized pragmas
2030                  */
2031                 OutBuffer buf;
2032                 buf.writestring(pd.ident.toString());
2033                 if (pd.args)
2034                 {
2035                     const errors_save = global.startGagging();
2036                     for (size_t i = 0; i < pd.args.dim; i++)
2037                     {
2038                         Expression e = (*pd.args)[i];
2039                         sc = sc.startCTFE();
2040                         e = e.expressionSemantic(sc);
2041                         e = resolveProperties(sc, e);
2042                         sc = sc.endCTFE();
2043                         e = e.ctfeInterpret();
2044                         if (i == 0)
2045                             buf.writestring(" (");
2046                         else
2047                             buf.writeByte(',');
2048                         buf.writestring(e.toChars());
2049                     }
2050                     if (pd.args.dim)
2051                         buf.writeByte(')');
2052                     global.endGagging(errors_save);
2053                 }
2054                 message("pragma    %s", buf.peekChars());
2055             }
2056         }
2057         else
2058             error(pd.loc, "unrecognized `pragma(%s)`", pd.ident.toChars());
2059     Ldecl:
2060         if (pd.decl)
2061         {
2062             Scope* sc2 = pd.newScope(sc);
2063             for (size_t i = 0; i < pd.decl.dim; i++)
2064             {
2065                 Dsymbol s = (*pd.decl)[i];
2066                 s.dsymbolSemantic(sc2);
2067                 if (pd.ident == Id.mangle)
2068                 {
2069                     assert(pd.args && pd.args.dim == 1);
2070                     if (auto se = (*pd.args)[0].toStringExp())
2071                     {
2072                         const name = (cast(const(char)[])se.peekData()).xarraydup;
2073                         uint cnt = setMangleOverride(s, name);
2074                         if (cnt > 1)
2075                             pd.error("can only apply to a single declaration");
2076                     }
2077                 }
2078             }
2079             if (sc2 != sc)
2080                 sc2.pop();
2081         }
2082         return;
2083     Lnodecl:
2084         if (pd.decl)
2085         {
2086             pd.error("is missing a terminating `;`");
2087             goto Ldecl;
2088             // do them anyway, to avoid segfaults.
2089         }
2090     }
2091 
2092     override void visit(StaticIfDeclaration sid)
2093     {
2094         attribSemantic(sid);
2095     }
2096 
2097     override void visit(StaticForeachDeclaration sfd)
2098     {
2099         attribSemantic(sfd);
2100     }
2101 
2102     private Dsymbols* compileIt(CompileDeclaration cd)
2103     {
2104         //printf("CompileDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars());
2105         OutBuffer buf;
2106         if (expressionsToString(buf, sc, cd.exps))
2107             return null;
2108 
2109         const errors = global.errors;
2110         const len = buf.length;
2111         buf.writeByte(0);
2112         const str = buf.extractSlice()[0 .. len];
2113         scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false);
2114         p.nextToken();
2115 
2116         auto d = p.parseDeclDefs(0);
2117         p.reportDiagnostics();
2118         if (global.errors != errors)
2119             return null;
2120 
2121         if (p.token.value != TOK.endOfFile)
2122         {
2123             cd.error("incomplete mixin declaration `%s`", str.ptr);
2124             return null;
2125         }
2126         return d;
2127     }
2128 
2129     /***********************************************************
2130      * https://dlang.org/spec/module.html#mixin-declaration
2131      */
2132     override void visit(CompileDeclaration cd)
2133     {
2134         //printf("CompileDeclaration::semantic()\n");
2135         if (!cd.compiled)
2136         {
2137             cd.decl = compileIt(cd);
2138             cd.AttribDeclaration.addMember(sc, cd.scopesym);
2139             cd.compiled = true;
2140 
2141             if (cd._scope && cd.decl)
2142             {
2143                 for (size_t i = 0; i < cd.decl.dim; i++)
2144                 {
2145                     Dsymbol s = (*cd.decl)[i];
2146                     s.setScope(cd._scope);
2147                 }
2148             }
2149         }
2150         attribSemantic(cd);
2151     }
2152 
2153     override void visit(CPPNamespaceDeclaration ns)
2154     {
2155         Identifier identFromSE (StringExp se)
2156         {
2157             const sident = se.toStringz();
2158             if (!sident.length || !Identifier.isValidIdentifier(sident))
2159             {
2160                 ns.exp.error("expected valid identifer for C++ namespace but got `%.*s`",
2161                              cast(int)sident.length, sident.ptr);
2162                 return null;
2163             }
2164             else
2165                 return Identifier.idPool(sident);
2166         }
2167 
2168         if (ns.ident is null)
2169         {
2170             ns.cppnamespace = sc.namespace;
2171             sc = sc.startCTFE();
2172             ns.exp = ns.exp.expressionSemantic(sc);
2173             ns.exp = resolveProperties(sc, ns.exp);
2174             sc = sc.endCTFE();
2175             ns.exp = ns.exp.ctfeInterpret();
2176             // Can be either a tuple of strings or a string itself
2177             if (auto te = ns.exp.isTupleExp())
2178             {
2179                 expandTuples(te.exps);
2180                 CPPNamespaceDeclaration current = ns.cppnamespace;
2181                 for (size_t d = 0; d < te.exps.dim; ++d)
2182                 {
2183                     auto exp = (*te.exps)[d];
2184                     auto prev = d ? current : ns.cppnamespace;
2185                     current = (d + 1) != te.exps.dim
2186                         ? new CPPNamespaceDeclaration(exp, null)
2187                         : ns;
2188                     current.exp = exp;
2189                     current.cppnamespace = prev;
2190                     if (auto se = exp.toStringExp())
2191                     {
2192                         current.ident = identFromSE(se);
2193                         if (current.ident is null)
2194                             return; // An error happened in `identFromSE`
2195                     }
2196                     else
2197                         ns.exp.error("`%s`: index %llu is not a string constant, it is a `%s`",
2198                                      ns.exp.toChars(), cast(ulong) d, ns.exp.type.toChars());
2199                 }
2200             }
2201             else if (auto se = ns.exp.toStringExp())
2202                 ns.ident = identFromSE(se);
2203             else
2204                 ns.exp.error("compile time string constant (or tuple) expected, not `%s`",
2205                              ns.exp.toChars());
2206         }
2207         if (ns.ident)
2208             attribSemantic(ns);
2209     }
2210 
2211     override void visit(UserAttributeDeclaration uad)
2212     {
2213         //printf("UserAttributeDeclaration::semantic() %p\n", this);
2214         if (uad.decl && !uad._scope)
2215             uad.Dsymbol.setScope(sc); // for function local symbols
2216         arrayExpressionSemantic(uad.atts, sc, true);
2217         return attribSemantic(uad);
2218     }
2219 
2220     override void visit(StaticAssert sa)
2221     {
2222         if (sa.semanticRun < PASS.semanticdone)
2223             sa.semanticRun = PASS.semanticdone;
2224     }
2225 
2226     override void visit(DebugSymbol ds)
2227     {
2228         //printf("DebugSymbol::semantic() %s\n", toChars());
2229         if (ds.semanticRun < PASS.semanticdone)
2230             ds.semanticRun = PASS.semanticdone;
2231     }
2232 
2233     override void visit(VersionSymbol vs)
2234     {
2235         if (vs.semanticRun < PASS.semanticdone)
2236             vs.semanticRun = PASS.semanticdone;
2237     }
2238 
2239     override void visit(Package pkg)
2240     {
2241         if (pkg.semanticRun < PASS.semanticdone)
2242             pkg.semanticRun = PASS.semanticdone;
2243     }
2244 
2245     override void visit(Module m)
2246     {
2247         if (m.semanticRun != PASS.init)
2248             return;
2249         //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
2250         m.semanticRun = PASS.semantic;
2251         // Note that modules get their own scope, from scratch.
2252         // This is so regardless of where in the syntax a module
2253         // gets imported, it is unaffected by context.
2254         Scope* sc = m._scope; // see if already got one from importAll()
2255         if (!sc)
2256         {
2257             Scope.createGlobal(m); // create root scope
2258         }
2259 
2260         //printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
2261         // Pass 1 semantic routines: do public side of the definition
2262         m.members.foreachDsymbol( (s)
2263         {
2264             //printf("\tModule('%s'): '%s'.dsymbolSemantic()\n", toChars(), s.toChars());
2265             s.dsymbolSemantic(sc);
2266             m.runDeferredSemantic();
2267         });
2268 
2269         if (m.userAttribDecl)
2270         {
2271             m.userAttribDecl.dsymbolSemantic(sc);
2272         }
2273         if (!m._scope)
2274         {
2275             sc = sc.pop();
2276             sc.pop(); // 2 pops because Scope::createGlobal() created 2
2277         }
2278         m.semanticRun = PASS.semanticdone;
2279         //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
2280     }
2281 
2282     override void visit(EnumDeclaration ed)
2283     {
2284         //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), toChars());
2285         //printf("EnumDeclaration::semantic() %p %s\n", this, toChars());
2286         if (ed.semanticRun >= PASS.semanticdone)
2287             return; // semantic() already completed
2288         if (ed.semanticRun == PASS.semantic)
2289         {
2290             assert(ed.memtype);
2291             error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
2292             ed.errors = true;
2293             ed.semanticRun = PASS.semanticdone;
2294             return;
2295         }
2296         uint dprogress_save = Module.dprogress;
2297 
2298         Scope* scx = null;
2299         if (ed._scope)
2300         {
2301             sc = ed._scope;
2302             scx = ed._scope; // save so we don't make redundant copies
2303             ed._scope = null;
2304         }
2305 
2306         if (!sc)
2307             return;
2308 
2309         ed.parent = sc.parent;
2310         ed.type = ed.type.typeSemantic(ed.loc, sc);
2311 
2312         ed.protection = sc.protection;
2313         if (sc.stc & STC.deprecated_)
2314             ed.isdeprecated = true;
2315         ed.userAttribDecl = sc.userAttribDecl;
2316         ed.cppnamespace = sc.namespace;
2317 
2318         ed.semanticRun = PASS.semantic;
2319         UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
2320 
2321         if (!ed.members && !ed.memtype) // enum ident;
2322         {
2323             ed.semanticRun = PASS.semanticdone;
2324             return;
2325         }
2326 
2327         if (!ed.symtab)
2328             ed.symtab = new DsymbolTable();
2329 
2330         /* The separate, and distinct, cases are:
2331          *  1. enum { ... }
2332          *  2. enum : memtype { ... }
2333          *  3. enum ident { ... }
2334          *  4. enum ident : memtype { ... }
2335          *  5. enum ident : memtype;
2336          *  6. enum ident;
2337          */
2338 
2339         if (ed.memtype)
2340         {
2341             ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
2342 
2343             /* Check to see if memtype is forward referenced
2344              */
2345             if (auto te = ed.memtype.isTypeEnum())
2346             {
2347                 EnumDeclaration sym = cast(EnumDeclaration)te.toDsymbol(sc);
2348                 if (!sym.memtype || !sym.members || !sym.symtab || sym._scope)
2349                 {
2350                     // memtype is forward referenced, so try again later
2351                     deferDsymbolSemantic(ed, scx);
2352                     Module.dprogress = dprogress_save;
2353                     //printf("\tdeferring %s\n", toChars());
2354                     ed.semanticRun = PASS.init;
2355                     return;
2356                 }
2357             }
2358             if (ed.memtype.ty == Tvoid)
2359             {
2360                 ed.error("base type must not be `void`");
2361                 ed.memtype = Type.terror;
2362             }
2363             if (ed.memtype.ty == Terror)
2364             {
2365                 ed.errors = true;
2366                 // poison all the members
2367                 ed.members.foreachDsymbol( (s) { s.errors = true; } );
2368                 ed.semanticRun = PASS.semanticdone;
2369                 return;
2370             }
2371         }
2372 
2373         ed.semanticRun = PASS.semanticdone;
2374 
2375         if (!ed.members) // enum ident : memtype;
2376             return;
2377 
2378         if (ed.members.dim == 0)
2379         {
2380             ed.error("enum `%s` must have at least one member", ed.toChars());
2381             ed.errors = true;
2382             return;
2383         }
2384 
2385         Module.dprogress++;
2386 
2387         Scope* sce;
2388         if (ed.isAnonymous())
2389             sce = sc;
2390         else
2391         {
2392             sce = sc.push(ed);
2393             sce.parent = ed;
2394         }
2395         sce = sce.startCTFE();
2396         sce.setNoFree(); // needed for getMaxMinValue()
2397 
2398         /* Each enum member gets the sce scope
2399          */
2400         ed.members.foreachDsymbol( (s)
2401         {
2402             EnumMember em = s.isEnumMember();
2403             if (em)
2404                 em._scope = sce;
2405         });
2406 
2407         if (!ed.added)
2408         {
2409             /* addMember() is not called when the EnumDeclaration appears as a function statement,
2410              * so we have to do what addMember() does and install the enum members in the right symbol
2411              * table
2412              */
2413             ScopeDsymbol scopesym = null;
2414             if (ed.isAnonymous())
2415             {
2416                 /* Anonymous enum members get added to enclosing scope.
2417                  */
2418                 for (Scope* sct = sce; 1; sct = sct.enclosing)
2419                 {
2420                     assert(sct);
2421                     if (sct.scopesym)
2422                     {
2423                         scopesym = sct.scopesym;
2424                         if (!sct.scopesym.symtab)
2425                             sct.scopesym.symtab = new DsymbolTable();
2426                         break;
2427                     }
2428                 }
2429             }
2430             else
2431             {
2432                 // Otherwise enum members are in the EnumDeclaration's symbol table
2433                 scopesym = ed;
2434             }
2435 
2436             ed.members.foreachDsymbol( (s)
2437             {
2438                 EnumMember em = s.isEnumMember();
2439                 if (em)
2440                 {
2441                     em.ed = ed;
2442                     em.addMember(sc, scopesym);
2443                 }
2444             });
2445         }
2446 
2447         ed.members.foreachDsymbol( (s)
2448         {
2449             EnumMember em = s.isEnumMember();
2450             if (em)
2451                 em.dsymbolSemantic(em._scope);
2452         });
2453         //printf("defaultval = %lld\n", defaultval);
2454 
2455         //if (defaultval) printf("defaultval: %s %s\n", defaultval.toChars(), defaultval.type.toChars());
2456         //printf("members = %s\n", members.toChars());
2457     }
2458 
2459     override void visit(EnumMember em)
2460     {
2461         //printf("EnumMember::semantic() %s\n", toChars());
2462 
2463         void errorReturn()
2464         {
2465             em.errors = true;
2466             em.semanticRun = PASS.semanticdone;
2467         }
2468 
2469         if (em.errors || em.semanticRun >= PASS.semanticdone)
2470             return;
2471         if (em.semanticRun == PASS.semantic)
2472         {
2473             em.error("circular reference to `enum` member");
2474             return errorReturn();
2475         }
2476         assert(em.ed);
2477 
2478         em.ed.dsymbolSemantic(sc);
2479         if (em.ed.errors)
2480             return errorReturn();
2481         if (em.errors || em.semanticRun >= PASS.semanticdone)
2482             return;
2483 
2484         if (em._scope)
2485             sc = em._scope;
2486         if (!sc)
2487             return;
2488 
2489         em.semanticRun = PASS.semantic;
2490 
2491         em.protection = em.ed.isAnonymous() ? em.ed.protection : Prot(Prot.Kind.public_);
2492         em.linkage = LINK.d;
2493         em.storage_class |= STC.manifest;
2494 
2495         // https://issues.dlang.org/show_bug.cgi?id=9701
2496         if (em.ed.isAnonymous())
2497         {
2498             if (em.userAttribDecl)
2499                 em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
2500             else
2501                 em.userAttribDecl = em.ed.userAttribDecl;
2502         }
2503 
2504         // Eval UDA in this same scope. Issues 19344, 20835, 21122
2505         if (em.userAttribDecl)
2506             em.userAttribDecl.setScope(sc);
2507 
2508         // The first enum member is special
2509         bool first = (em == (*em.ed.members)[0]);
2510 
2511         if (em.origType)
2512         {
2513             em.origType = em.origType.typeSemantic(em.loc, sc);
2514             em.type = em.origType;
2515             assert(em.value); // "type id;" is not a valid enum member declaration
2516         }
2517 
2518         if (em.value)
2519         {
2520             Expression e = em.value;
2521             assert(e.dyncast() == DYNCAST.expression);
2522             e = e.expressionSemantic(sc);
2523             e = resolveProperties(sc, e);
2524             e = e.ctfeInterpret();
2525             if (e.op == TOK.error)
2526                 return errorReturn();
2527             if (first && !em.ed.memtype && !em.ed.isAnonymous())
2528             {
2529                 em.ed.memtype = e.type;
2530                 if (em.ed.memtype.ty == Terror)
2531                 {
2532                     em.ed.errors = true;
2533                     return errorReturn();
2534                 }
2535                 if (em.ed.memtype.ty != Terror)
2536                 {
2537                     /* https://issues.dlang.org/show_bug.cgi?id=11746
2538                      * All of named enum members should have same type
2539                      * with the first member. If the following members were referenced
2540                      * during the first member semantic, their types should be unified.
2541                      */
2542                     em.ed.members.foreachDsymbol( (s)
2543                     {
2544                         EnumMember enm = s.isEnumMember();
2545                         if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
2546                             return;
2547 
2548                         //printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
2549                         Expression ev = enm.value;
2550                         ev = ev.implicitCastTo(sc, em.ed.memtype);
2551                         ev = ev.ctfeInterpret();
2552                         ev = ev.castTo(sc, em.ed.type);
2553                         if (ev.op == TOK.error)
2554                             em.ed.errors = true;
2555                         enm.value = ev;
2556                     });
2557 
2558                     if (em.ed.errors)
2559                     {
2560                         em.ed.memtype = Type.terror;
2561                         return errorReturn();
2562                     }
2563                 }
2564             }
2565 
2566             if (em.ed.memtype && !em.origType)
2567             {
2568                 e = e.implicitCastTo(sc, em.ed.memtype);
2569                 e = e.ctfeInterpret();
2570 
2571                 // save origValue for better json output
2572                 em.origValue = e;
2573 
2574                 if (!em.ed.isAnonymous())
2575                 {
2576                     e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
2577                     e = e.ctfeInterpret();
2578                 }
2579             }
2580             else if (em.origType)
2581             {
2582                 e = e.implicitCastTo(sc, em.origType);
2583                 e = e.ctfeInterpret();
2584                 assert(em.ed.isAnonymous());
2585 
2586                 // save origValue for better json output
2587                 em.origValue = e;
2588             }
2589             em.value = e;
2590         }
2591         else if (first)
2592         {
2593             Type t;
2594             if (em.ed.memtype)
2595                 t = em.ed.memtype;
2596             else
2597             {
2598                 t = Type.tint32;
2599                 if (!em.ed.isAnonymous())
2600                     em.ed.memtype = t;
2601             }
2602             Expression e = new IntegerExp(em.loc, 0, t);
2603             e = e.ctfeInterpret();
2604 
2605             // save origValue for better json output
2606             em.origValue = e;
2607 
2608             if (!em.ed.isAnonymous())
2609             {
2610                 e = e.castTo(sc, em.ed.type);
2611                 e = e.ctfeInterpret();
2612             }
2613             em.value = e;
2614         }
2615         else
2616         {
2617             /* Find the previous enum member,
2618              * and set this to be the previous value + 1
2619              */
2620             EnumMember emprev = null;
2621             em.ed.members.foreachDsymbol( (s)
2622             {
2623                 if (auto enm = s.isEnumMember())
2624                 {
2625                     if (enm == em)
2626                         return 1;       // found
2627                     emprev = enm;
2628                 }
2629                 return 0;       // continue
2630             });
2631 
2632             assert(emprev);
2633             if (emprev.semanticRun < PASS.semanticdone) // if forward reference
2634                 emprev.dsymbolSemantic(emprev._scope); // resolve it
2635             if (emprev.errors)
2636                 return errorReturn();
2637 
2638             Expression eprev = emprev.value;
2639             // .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
2640             Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
2641                 ? em.ed.memtype
2642                 : eprev.type;
2643 
2644             Expression emax = tprev.getProperty(sc, em.ed.loc, Id.max, 0);
2645             emax = emax.expressionSemantic(sc);
2646             emax = emax.ctfeInterpret();
2647 
2648             // Set value to (eprev + 1).
2649             // But first check that (eprev != emax)
2650             assert(eprev);
2651             Expression e = new EqualExp(TOK.equal, em.loc, eprev, emax);
2652             e = e.expressionSemantic(sc);
2653             e = e.ctfeInterpret();
2654             if (e.toInteger())
2655             {
2656                 em.error("initialization with `%s.%s+1` causes overflow for type `%s`",
2657                     emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars());
2658                 return errorReturn();
2659             }
2660 
2661             // Now set e to (eprev + 1)
2662             e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
2663             e = e.expressionSemantic(sc);
2664             e = e.castTo(sc, eprev.type);
2665             e = e.ctfeInterpret();
2666 
2667             // save origValue (without cast) for better json output
2668             if (e.op != TOK.error) // avoid duplicate diagnostics
2669             {
2670                 assert(emprev.origValue);
2671                 em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
2672                 em.origValue = em.origValue.expressionSemantic(sc);
2673                 em.origValue = em.origValue.ctfeInterpret();
2674             }
2675 
2676             if (e.op == TOK.error)
2677                 return errorReturn();
2678             if (e.type.isfloating())
2679             {
2680                 // Check that e != eprev (not always true for floats)
2681                 Expression etest = new EqualExp(TOK.equal, em.loc, e, eprev);
2682                 etest = etest.expressionSemantic(sc);
2683                 etest = etest.ctfeInterpret();
2684                 if (etest.toInteger())
2685                 {
2686                     em.error("has inexact value due to loss of precision");
2687                     return errorReturn();
2688                 }
2689             }
2690             em.value = e;
2691         }
2692         if (!em.origType)
2693             em.type = em.value.type;
2694 
2695         assert(em.origValue);
2696         em.semanticRun = PASS.semanticdone;
2697     }
2698 
2699     override void visit(TemplateDeclaration tempdecl)
2700     {
2701         static if (LOG)
2702         {
2703             printf("TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\n", this, tempdecl.ident.toChars());
2704             printf("sc.stc = %llx\n", sc.stc);
2705             printf("sc.module = %s\n", sc._module.toChars());
2706         }
2707         if (tempdecl.semanticRun != PASS.init)
2708             return; // semantic() already run
2709 
2710         if (tempdecl._scope)
2711         {
2712             sc = tempdecl._scope;
2713             tempdecl._scope = null;
2714         }
2715         if (!sc)
2716             return;
2717 
2718         // Remember templates defined in module object that we need to know about
2719         if (sc._module && sc._module.ident == Id.object)
2720         {
2721             if (tempdecl.ident == Id.RTInfo)
2722                 Type.rtinfo = tempdecl;
2723         }
2724 
2725         /* Remember Scope for later instantiations, but make
2726          * a copy since attributes can change.
2727          */
2728         if (!tempdecl._scope)
2729         {
2730             tempdecl._scope = sc.copy();
2731             tempdecl._scope.setNoFree();
2732         }
2733 
2734         tempdecl.semanticRun = PASS.semantic;
2735 
2736         tempdecl.parent = sc.parent;
2737         tempdecl.protection = sc.protection;
2738         tempdecl.cppnamespace = sc.namespace;
2739         tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);
2740         tempdecl.deprecated_ = !!(sc.stc & STC.deprecated_);
2741 
2742         UserAttributeDeclaration.checkGNUABITag(tempdecl, sc.linkage);
2743 
2744         if (!tempdecl.isstatic)
2745         {
2746             if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())
2747                 ad.makeNested();
2748         }
2749 
2750         // Set up scope for parameters
2751         auto paramsym = new ScopeDsymbol();
2752         paramsym.parent = tempdecl.parent;
2753         Scope* paramscope = sc.push(paramsym);
2754         paramscope.stc = 0;
2755 
2756         if (global.params.doDocComments)
2757         {
2758             tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);
2759             for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2760             {
2761                 TemplateParameter tp = (*tempdecl.parameters)[i];
2762                 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
2763             }
2764         }
2765 
2766         for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2767         {
2768             TemplateParameter tp = (*tempdecl.parameters)[i];
2769             if (!tp.declareParameter(paramscope))
2770             {
2771                 error(tp.loc, "parameter `%s` multiply defined", tp.ident.toChars());
2772                 tempdecl.errors = true;
2773             }
2774             if (!tp.tpsemantic(paramscope, tempdecl.parameters))
2775             {
2776                 tempdecl.errors = true;
2777             }
2778             if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())
2779             {
2780                 tempdecl.error("template tuple parameter must be last one");
2781                 tempdecl.errors = true;
2782             }
2783         }
2784 
2785         /* Calculate TemplateParameter.dependent
2786          */
2787         TemplateParameters tparams = TemplateParameters(1);
2788         for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2789         {
2790             TemplateParameter tp = (*tempdecl.parameters)[i];
2791             tparams[0] = tp;
2792 
2793             for (size_t j = 0; j < tempdecl.parameters.dim; j++)
2794             {
2795                 // Skip cases like: X(T : T)
2796                 if (i == j)
2797                     continue;
2798 
2799                 if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())
2800                 {
2801                     if (reliesOnTident(ttp.specType, &tparams))
2802                         tp.dependent = true;
2803                 }
2804                 else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())
2805                 {
2806                     if (reliesOnTident(tap.specType, &tparams) ||
2807                         reliesOnTident(isType(tap.specAlias), &tparams))
2808                     {
2809                         tp.dependent = true;
2810                     }
2811                 }
2812             }
2813         }
2814 
2815         paramscope.pop();
2816 
2817         // Compute again
2818         tempdecl.onemember = null;
2819         if (tempdecl.members)
2820         {
2821             Dsymbol s;
2822             if (Dsymbol.oneMembers(tempdecl.members, &s, tempdecl.ident) && s)
2823             {
2824                 tempdecl.onemember = s;
2825                 s.parent = tempdecl;
2826             }
2827         }
2828 
2829         /* BUG: should check:
2830          *  1. template functions must not introduce virtual functions, as they
2831          *     cannot be accomodated in the vtbl[]
2832          *  2. templates cannot introduce non-static data members (i.e. fields)
2833          *     as they would change the instance size of the aggregate.
2834          */
2835 
2836         tempdecl.semanticRun = PASS.semanticdone;
2837     }
2838 
2839     override void visit(TemplateInstance ti)
2840     {
2841         templateInstanceSemantic(ti, sc, null);
2842     }
2843 
2844     override void visit(TemplateMixin tm)
2845     {
2846         static if (LOG)
2847         {
2848             printf("+TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
2849             fflush(stdout);
2850         }
2851         if (tm.semanticRun != PASS.init)
2852         {
2853             // When a class/struct contains mixin members, and is done over
2854             // because of forward references, never reach here so semanticRun
2855             // has been reset to PASS.init.
2856             static if (LOG)
2857             {
2858                 printf("\tsemantic done\n");
2859             }
2860             return;
2861         }
2862         tm.semanticRun = PASS.semantic;
2863         static if (LOG)
2864         {
2865             printf("\tdo semantic\n");
2866         }
2867 
2868         Scope* scx = null;
2869         if (tm._scope)
2870         {
2871             sc = tm._scope;
2872             scx = tm._scope; // save so we don't make redundant copies
2873             tm._scope = null;
2874         }
2875 
2876         /* Run semantic on each argument, place results in tiargs[],
2877          * then find best match template with tiargs
2878          */
2879         if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, null))
2880         {
2881             if (tm.semanticRun == PASS.init) // forward reference had occurred
2882             {
2883                 //printf("forward reference - deferring\n");
2884                 return deferDsymbolSemantic(tm, scx);
2885             }
2886 
2887             tm.inst = tm;
2888             tm.errors = true;
2889             return; // error recovery
2890         }
2891 
2892         auto tempdecl = tm.tempdecl.isTemplateDeclaration();
2893         assert(tempdecl);
2894 
2895         if (!tm.ident)
2896         {
2897             /* Assign scope local unique identifier, as same as lambdas.
2898              */
2899             const(char)[] s = "__mixin";
2900 
2901             if (FuncDeclaration func = sc.parent.isFuncDeclaration())
2902             {
2903                 tm.symtab = func.localsymtab;
2904                 if (tm.symtab)
2905                 {
2906                     // Inside template constraint, symtab is not set yet.
2907                     goto L1;
2908                 }
2909             }
2910             else
2911             {
2912                 tm.symtab = sc.parent.isScopeDsymbol().symtab;
2913             L1:
2914                 assert(tm.symtab);
2915                 tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
2916                 tm.symtab.insert(tm);
2917             }
2918         }
2919 
2920         tm.inst = tm;
2921         tm.parent = sc.parent;
2922 
2923         /* Detect recursive mixin instantiations.
2924          */
2925         for (Dsymbol s = tm.parent; s; s = s.parent)
2926         {
2927             //printf("\ts = '%s'\n", s.toChars());
2928             TemplateMixin tmix = s.isTemplateMixin();
2929             if (!tmix || tempdecl != tmix.tempdecl)
2930                 continue;
2931 
2932             /* Different argument list lengths happen with variadic args
2933              */
2934             if (tm.tiargs.dim != tmix.tiargs.dim)
2935                 continue;
2936 
2937             for (size_t i = 0; i < tm.tiargs.dim; i++)
2938             {
2939                 RootObject o = (*tm.tiargs)[i];
2940                 Type ta = isType(o);
2941                 Expression ea = isExpression(o);
2942                 Dsymbol sa = isDsymbol(o);
2943                 RootObject tmo = (*tmix.tiargs)[i];
2944                 if (ta)
2945                 {
2946                     Type tmta = isType(tmo);
2947                     if (!tmta)
2948                         goto Lcontinue;
2949                     if (!ta.equals(tmta))
2950                         goto Lcontinue;
2951                 }
2952                 else if (ea)
2953                 {
2954                     Expression tme = isExpression(tmo);
2955                     if (!tme || !ea.equals(tme))
2956                         goto Lcontinue;
2957                 }
2958                 else if (sa)
2959                 {
2960                     Dsymbol tmsa = isDsymbol(tmo);
2961                     if (sa != tmsa)
2962                         goto Lcontinue;
2963                 }
2964                 else
2965                     assert(0);
2966             }
2967             tm.error("recursive mixin instantiation");
2968             return;
2969 
2970         Lcontinue:
2971             continue;
2972         }
2973 
2974         // Copy the syntax trees from the TemplateDeclaration
2975         tm.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
2976         if (!tm.members)
2977             return;
2978 
2979         tm.symtab = new DsymbolTable();
2980 
2981         for (Scope* sce = sc; 1; sce = sce.enclosing)
2982         {
2983             ScopeDsymbol sds = sce.scopesym;
2984             if (sds)
2985             {
2986                 sds.importScope(tm, Prot(Prot.Kind.public_));
2987                 break;
2988             }
2989         }
2990 
2991         static if (LOG)
2992         {
2993             printf("\tcreate scope for template parameters '%s'\n", tm.toChars());
2994         }
2995         Scope* scy = sc.push(tm);
2996         scy.parent = tm;
2997 
2998         /* https://issues.dlang.org/show_bug.cgi?id=930
2999          *
3000          * If the template that is to be mixed in is in the scope of a template
3001          * instance, we have to also declare the type aliases in the new mixin scope.
3002          */
3003         auto parentInstance = tempdecl.parent ? tempdecl.parent.isTemplateInstance() : null;
3004         if (parentInstance)
3005             parentInstance.declareParameters(scy);
3006 
3007         tm.argsym = new ScopeDsymbol();
3008         tm.argsym.parent = scy.parent;
3009         Scope* argscope = scy.push(tm.argsym);
3010 
3011         uint errorsave = global.errors;
3012 
3013         // Declare each template parameter as an alias for the argument type
3014         tm.declareParameters(argscope);
3015 
3016         // Add members to enclosing scope, as well as this scope
3017         tm.members.foreachDsymbol(s => s.addMember(argscope, tm));
3018 
3019         // Do semantic() analysis on template instance members
3020         static if (LOG)
3021         {
3022             printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
3023         }
3024         Scope* sc2 = argscope.push(tm);
3025         //size_t deferred_dim = Module.deferred.dim;
3026 
3027         __gshared int nest;
3028         //printf("%d\n", nest);
3029         if (++nest > global.recursionLimit)
3030         {
3031             global.gag = 0; // ensure error message gets printed
3032             tm.error("recursive expansion");
3033             fatal();
3034         }
3035 
3036         tm.members.foreachDsymbol( s => s.setScope(sc2) );
3037 
3038         tm.members.foreachDsymbol( s => s.importAll(sc2) );
3039 
3040         tm.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
3041 
3042         nest--;
3043 
3044         /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
3045          * Because the members would already call Module.addDeferredSemantic() for themselves.
3046          * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
3047          */
3048         //if (!sc.func && Module.deferred.dim > deferred_dim) {}
3049 
3050         AggregateDeclaration ad = tm.toParent().isAggregateDeclaration();
3051         if (sc.func && !ad)
3052         {
3053             tm.semantic2(sc2);
3054             tm.semantic3(sc2);
3055         }
3056 
3057         // Give additional context info if error occurred during instantiation
3058         if (global.errors != errorsave)
3059         {
3060             tm.error("error instantiating");
3061             tm.errors = true;
3062         }
3063 
3064         sc2.pop();
3065         argscope.pop();
3066         scy.pop();
3067 
3068         static if (LOG)
3069         {
3070             printf("-TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
3071         }
3072     }
3073 
3074     override void visit(Nspace ns)
3075     {
3076         if (ns.semanticRun != PASS.init)
3077             return;
3078         static if (LOG)
3079         {
3080             printf("+Nspace::semantic('%s')\n", ns.toChars());
3081         }
3082         if (ns._scope)
3083         {
3084             sc = ns._scope;
3085             ns._scope = null;
3086         }
3087         if (!sc)
3088             return;
3089 
3090         bool repopulateMembers = false;
3091         if (ns.identExp)
3092         {
3093             // resolve the namespace identifier
3094             sc = sc.startCTFE();
3095             Expression resolved = ns.identExp.expressionSemantic(sc);
3096             resolved = resolveProperties(sc, resolved);
3097             sc = sc.endCTFE();
3098             resolved = resolved.ctfeInterpret();
3099             StringExp name = resolved.toStringExp();
3100             TupleExp tup = name ? null : resolved.toTupleExp();
3101             if (!tup && !name)
3102             {
3103                 error(ns.loc, "expected string expression for namespace name, got `%s`", ns.identExp.toChars());
3104                 return;
3105             }
3106             ns.identExp = resolved; // we don't need to keep the old AST around
3107             if (name)
3108             {
3109                 const(char)[] ident = name.toStringz();
3110                 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
3111                 {
3112                     error(ns.loc, "expected valid identifer for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
3113                     return;
3114                 }
3115                 ns.ident = Identifier.idPool(ident);
3116             }
3117             else
3118             {
3119                 // create namespace stack from the tuple
3120                 Nspace parentns = ns;
3121                 foreach (i, exp; *tup.exps)
3122                 {
3123                     name = exp.toStringExp();
3124                     if (!name)
3125                     {
3126                         error(ns.loc, "expected string expression for namespace name, got `%s`", exp.toChars());
3127                         return;
3128                     }
3129                     const(char)[] ident = name.toStringz();
3130                     if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
3131                     {
3132                         error(ns.loc, "expected valid identifer for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
3133                         return;
3134                     }
3135                     if (i == 0)
3136                     {
3137                         ns.ident = Identifier.idPool(ident);
3138                     }
3139                     else
3140                     {
3141                         // insert the new namespace
3142                         Nspace childns = new Nspace(ns.loc, Identifier.idPool(ident), null, parentns.members);
3143                         parentns.members = new Dsymbols;
3144                         parentns.members.push(childns);
3145                         parentns = childns;
3146                         repopulateMembers = true;
3147                     }
3148                 }
3149             }
3150         }
3151 
3152         ns.semanticRun = PASS.semantic;
3153         ns.parent = sc.parent;
3154         // Link does not matter here, if the UDA is present it will error
3155         UserAttributeDeclaration.checkGNUABITag(ns, LINK.cpp);
3156 
3157         if (ns.members)
3158         {
3159             assert(sc);
3160             sc = sc.push(ns);
3161             sc.linkage = LINK.cpp; // note that namespaces imply C++ linkage
3162             sc.parent = ns;
3163             foreach (s; *ns.members)
3164             {
3165                 if (repopulateMembers)
3166                 {
3167                     s.addMember(sc, sc.scopesym);
3168                     s.setScope(sc);
3169                 }
3170                 s.importAll(sc);
3171             }
3172             foreach (s; *ns.members)
3173             {
3174                 static if (LOG)
3175                 {
3176                     printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
3177                 }
3178                 s.dsymbolSemantic(sc);
3179             }
3180             sc.pop();
3181         }
3182         ns.semanticRun = PASS.semanticdone;
3183         static if (LOG)
3184         {
3185             printf("-Nspace::semantic('%s')\n", ns.toChars());
3186         }
3187     }
3188 
3189     void funcDeclarationSemantic(FuncDeclaration funcdecl)
3190     {
3191         TypeFunction f;
3192         AggregateDeclaration ad;
3193         InterfaceDeclaration id;
3194 
3195         version (none)
3196         {
3197             printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, funcdecl, funcdecl.toPrettyChars(), sc.linkage);
3198             if (funcdecl.isFuncLiteralDeclaration())
3199                 printf("\tFuncLiteralDeclaration()\n");
3200             printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), funcdecl.parent ? funcdecl.parent.toChars() : "");
3201             printf("type: %p, %s\n", funcdecl.type, funcdecl.type.toChars());
3202         }
3203 
3204         if (funcdecl.semanticRun != PASS.init && funcdecl.isFuncLiteralDeclaration())
3205         {
3206             /* Member functions that have return types that are
3207              * forward references can have semantic() run more than
3208              * once on them.
3209              * See test\interface2.d, test20
3210              */
3211             return;
3212         }
3213 
3214         if (funcdecl.semanticRun >= PASS.semanticdone)
3215             return;
3216         assert(funcdecl.semanticRun <= PASS.semantic);
3217         funcdecl.semanticRun = PASS.semantic;
3218 
3219         if (funcdecl._scope)
3220         {
3221             sc = funcdecl._scope;
3222             funcdecl._scope = null;
3223         }
3224 
3225         if (!sc || funcdecl.errors)
3226             return;
3227 
3228         funcdecl.cppnamespace = sc.namespace;
3229         funcdecl.parent = sc.parent;
3230         Dsymbol parent = funcdecl.toParent();
3231 
3232         funcdecl.foverrides.setDim(0); // reset in case semantic() is being retried for this function
3233 
3234         funcdecl.storage_class |= sc.stc & ~STC.ref_;
3235         ad = funcdecl.isThis();
3236         // Don't nest structs b/c of generated methods which should not access the outer scopes.
3237         // https://issues.dlang.org/show_bug.cgi?id=16627
3238         if (ad && !funcdecl.generated)
3239         {
3240             funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_);
3241             ad.makeNested();
3242         }
3243         if (sc.func)
3244             funcdecl.storage_class |= sc.func.storage_class & STC.disable;
3245         // Remove prefix storage classes silently.
3246         if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
3247             funcdecl.storage_class &= ~STC.TYPECTOR;
3248 
3249         //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration::isFinal());
3250 
3251         if (sc.flags & SCOPE.compile)
3252             funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
3253 
3254         FuncLiteralDeclaration fld = funcdecl.isFuncLiteralDeclaration();
3255         if (fld && fld.treq)
3256         {
3257             Type treq = fld.treq;
3258             assert(treq.nextOf().ty == Tfunction);
3259             if (treq.ty == Tdelegate)
3260                 fld.tok = TOK.delegate_;
3261             else if (treq.ty == Tpointer && treq.nextOf().ty == Tfunction)
3262                 fld.tok = TOK.function_;
3263             else
3264                 assert(0);
3265             funcdecl.linkage = treq.nextOf().toTypeFunction().linkage;
3266         }
3267         else
3268             funcdecl.linkage = sc.linkage;
3269         funcdecl.inlining = sc.inlining;
3270         funcdecl.protection = sc.protection;
3271         funcdecl.userAttribDecl = sc.userAttribDecl;
3272         UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage);
3273 
3274         if (!funcdecl.originalType)
3275             funcdecl.originalType = funcdecl.type.syntaxCopy();
3276         if (funcdecl.type.ty != Tfunction)
3277         {
3278             if (funcdecl.type.ty != Terror)
3279             {
3280                 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
3281                 funcdecl.type = Type.terror;
3282             }
3283             funcdecl.errors = true;
3284             return;
3285         }
3286         if (!funcdecl.type.deco)
3287         {
3288             sc = sc.push();
3289             sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
3290 
3291             TypeFunction tf = funcdecl.type.toTypeFunction();
3292             if (sc.func)
3293             {
3294                 /* If the nesting parent is pure without inference,
3295                  * then this function defaults to pure too.
3296                  *
3297                  *  auto foo() pure {
3298                  *    auto bar() {}     // become a weak purity function
3299                  *    class C {         // nested class
3300                  *      auto baz() {}   // become a weak purity function
3301                  *    }
3302                  *
3303                  *    static auto boo() {}   // typed as impure
3304                  *    // Even though, boo cannot call any impure functions.
3305                  *    // See also Expression::checkPurity().
3306                  *  }
3307                  */
3308                 if (tf.purity == PURE.impure && (funcdecl.isNested() || funcdecl.isThis()))
3309                 {
3310                     FuncDeclaration fd = null;
3311                     for (Dsymbol p = funcdecl.toParent2(); p; p = p.toParent2())
3312                     {
3313                         if (AggregateDeclaration adx = p.isAggregateDeclaration())
3314                         {
3315                             if (adx.isNested())
3316                                 continue;
3317                             break;
3318                         }
3319                         if ((fd = p.isFuncDeclaration()) !is null)
3320                             break;
3321                     }
3322 
3323                     /* If the parent's purity is inferred, then this function's purity needs
3324                      * to be inferred first.
3325                      */
3326                     if (fd && fd.isPureBypassingInference() >= PURE.weak && !funcdecl.isInstantiated())
3327                     {
3328                         tf.purity = PURE.fwdref; // default to pure
3329                     }
3330                 }
3331             }
3332 
3333             if (tf.isref)
3334                 sc.stc |= STC.ref_;
3335             if (tf.isScopeQual)
3336                 sc.stc |= STC.scope_;
3337             if (tf.isnothrow)
3338                 sc.stc |= STC.nothrow_;
3339             if (tf.isnogc)
3340                 sc.stc |= STC.nogc;
3341             if (tf.isproperty)
3342                 sc.stc |= STC.property;
3343             if (tf.purity == PURE.fwdref)
3344                 sc.stc |= STC.pure_;
3345             if (tf.trust != TRUST.default_)
3346                 sc.stc &= ~STC.safeGroup;
3347             if (tf.trust == TRUST.safe)
3348                 sc.stc |= STC.safe;
3349             if (tf.trust == TRUST.system)
3350                 sc.stc |= STC.system;
3351             if (tf.trust == TRUST.trusted)
3352                 sc.stc |= STC.trusted;
3353 
3354             if (funcdecl.isCtorDeclaration())
3355             {
3356                 sc.flags |= SCOPE.ctor;
3357                 Type tret = ad.handleType();
3358                 assert(tret);
3359                 tret = tret.addStorageClass(funcdecl.storage_class | sc.stc);
3360                 tret = tret.addMod(funcdecl.type.mod);
3361                 tf.next = tret;
3362                 if (ad.isStructDeclaration())
3363                     sc.stc |= STC.ref_;
3364             }
3365 
3366             // 'return' on a non-static class member function implies 'scope' as well
3367             if (ad && ad.isClassDeclaration() && (tf.isreturn || sc.stc & STC.return_) && !(sc.stc & STC.static_))
3368                 sc.stc |= STC.scope_;
3369 
3370             // If 'this' has no pointers, remove 'scope' as it has no meaning
3371             if (sc.stc & STC.scope_ && ad && ad.isStructDeclaration() && !ad.type.hasPointers())
3372             {
3373                 sc.stc &= ~STC.scope_;
3374                 tf.isScopeQual = false;
3375             }
3376 
3377             sc.linkage = funcdecl.linkage;
3378 
3379             if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
3380             {
3381                 OutBuffer buf;
3382                 MODtoBuffer(&buf, tf.mod);
3383                 funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
3384                 tf.mod = 0; // remove qualifiers
3385             }
3386 
3387             /* Apply const, immutable, wild and shared storage class
3388              * to the function type. Do this before type semantic.
3389              */
3390             auto stc = funcdecl.storage_class;
3391             if (funcdecl.type.isImmutable())
3392                 stc |= STC.immutable_;
3393             if (funcdecl.type.isConst())
3394                 stc |= STC.const_;
3395             if (funcdecl.type.isShared() || funcdecl.storage_class & STC.synchronized_)
3396                 stc |= STC.shared_;
3397             if (funcdecl.type.isWild())
3398                 stc |= STC.wild;
3399             funcdecl.type = funcdecl.type.addSTC(stc);
3400 
3401             funcdecl.type = funcdecl.type.typeSemantic(funcdecl.loc, sc);
3402             sc = sc.pop();
3403         }
3404         if (funcdecl.type.ty != Tfunction)
3405         {
3406             if (funcdecl.type.ty != Terror)
3407             {
3408                 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
3409                 funcdecl.type = Type.terror;
3410             }
3411             funcdecl.errors = true;
3412             return;
3413         }
3414         else
3415         {
3416             // Merge back function attributes into 'originalType'.
3417             // It's used for mangling, ddoc, and json output.
3418             TypeFunction tfo = funcdecl.originalType.toTypeFunction();
3419             TypeFunction tfx = funcdecl.type.toTypeFunction();
3420             tfo.mod = tfx.mod;
3421             tfo.isScopeQual = tfx.isScopeQual;
3422             tfo.isreturninferred = tfx.isreturninferred;
3423             tfo.isscopeinferred = tfx.isscopeinferred;
3424             tfo.isref = tfx.isref;
3425             tfo.isnothrow = tfx.isnothrow;
3426             tfo.isnogc = tfx.isnogc;
3427             tfo.isproperty = tfx.isproperty;
3428             tfo.purity = tfx.purity;
3429             tfo.trust = tfx.trust;
3430 
3431             funcdecl.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);
3432         }
3433 
3434         f = cast(TypeFunction)funcdecl.type;
3435 
3436         if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)
3437             funcdecl.error("storage class `auto` has no effect if return type is not inferred");
3438 
3439         /* Functions can only be 'scope' if they have a 'this'
3440          */
3441         if (f.isScopeQual && !funcdecl.isNested() && !ad)
3442         {
3443             funcdecl.error("functions cannot be `scope`");
3444         }
3445 
3446         if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())
3447         {
3448             /* Non-static nested functions have a hidden 'this' pointer to which
3449              * the 'return' applies
3450              */
3451             if (sc.scopesym && sc.scopesym.isAggregateDeclaration())
3452                 funcdecl.error("`static` member has no `this` to which `return` can apply");
3453             else
3454                 error(funcdecl.loc, "Top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars());
3455         }
3456 
3457         if (funcdecl.isAbstract() && !funcdecl.isVirtual())
3458         {
3459             const(char)* sfunc;
3460             if (funcdecl.isStatic())
3461                 sfunc = "static";
3462             else if (funcdecl.protection.kind == Prot.Kind.private_ || funcdecl.protection.kind == Prot.Kind.package_)
3463                 sfunc = protectionToChars(funcdecl.protection.kind);
3464             else
3465                 sfunc = "final";
3466             funcdecl.error("`%s` functions cannot be `abstract`", sfunc);
3467         }
3468 
3469         if (funcdecl.isOverride() && !funcdecl.isVirtual() && !funcdecl.isFuncLiteralDeclaration())
3470         {
3471             Prot.Kind kind = funcdecl.prot().kind;
3472             if ((kind == Prot.Kind.private_ || kind == Prot.Kind.package_) && funcdecl.isMember())
3473                 funcdecl.error("`%s` method is not virtual and cannot override", protectionToChars(kind));
3474             else
3475                 funcdecl.error("cannot override a non-virtual function");
3476         }
3477 
3478         if (funcdecl.isAbstract() && funcdecl.isFinalFunc())
3479             funcdecl.error("cannot be both `final` and `abstract`");
3480         version (none)
3481         {
3482             if (funcdecl.isAbstract() && funcdecl.fbody)
3483                 funcdecl.error("`abstract` functions cannot have bodies");
3484         }
3485 
3486         version (none)
3487         {
3488             if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())
3489             {
3490                 if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
3491                     funcdecl.error("static constructors / destructors must be `static void`");
3492                 if (f.arguments && f.arguments.dim)
3493                     funcdecl.error("static constructors / destructors must have empty parameter list");
3494                 // BUG: check for invalid storage classes
3495             }
3496         }
3497 
3498         if (const pors = sc.flags & (SCOPE.printf | SCOPE.scanf))
3499         {
3500             /* printf/scanf-like functions must be of the form:
3501              *    extern (C/C++) T printf([parameters...], const(char)* format, ...);
3502              * or:
3503              *    extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
3504              */
3505 
3506             static bool isPointerToChar(Parameter p)
3507             {
3508                 if (auto tptr = p.type.isTypePointer())
3509                 {
3510                     return tptr.next.ty == Tchar;
3511                 }
3512                 return false;
3513             }
3514 
3515             bool isVa_list(Parameter p)
3516             {
3517                 return p.type.equals(target.va_listType(funcdecl.loc, sc));
3518             }
3519 
3520             const nparams = f.parameterList.length;
3521             if ((f.linkage == LINK.c || f.linkage == LINK.cpp) &&
3522 
3523                 (f.parameterList.varargs == VarArg.variadic &&
3524                  nparams >= 1 &&
3525                  isPointerToChar(f.parameterList[nparams - 1]) ||
3526 
3527                  f.parameterList.varargs == VarArg.none &&
3528                  nparams >= 2 &&
3529                  isPointerToChar(f.parameterList[nparams - 2]) &&
3530                  isVa_list(f.parameterList[nparams - 1])
3531                 )
3532                )
3533             {
3534                 funcdecl.flags |= (pors == SCOPE.printf) ? FUNCFLAG.printf : FUNCFLAG.scanf;
3535             }
3536             else
3537             {
3538                 const p = (pors == SCOPE.printf ? Id.printf : Id.scanf).toChars();
3539                 if (f.parameterList.varargs == VarArg.variadic)
3540                 {
3541                     funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`"
3542                                    ~ " not `%s`",
3543                         p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
3544                 }
3545                 else
3546                 {
3547                     funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`",
3548                         p, f.next.toChars(), funcdecl.toChars());
3549                 }
3550             }
3551         }
3552 
3553         id = parent.isInterfaceDeclaration();
3554         if (id)
3555         {
3556             funcdecl.storage_class |= STC.abstract_;
3557             if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete())
3558                 funcdecl.error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", id.toChars());
3559             if (funcdecl.fbody && funcdecl.isVirtual())
3560                 funcdecl.error("function body only allowed in `final` functions in interface `%s`", id.toChars());
3561         }
3562         if (UnionDeclaration ud = parent.isUnionDeclaration())
3563         {
3564             if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration())
3565                 funcdecl.error("destructors, postblits and invariants are not allowed in union `%s`", ud.toChars());
3566         }
3567 
3568         if (StructDeclaration sd = parent.isStructDeclaration())
3569         {
3570             if (funcdecl.isCtorDeclaration())
3571             {
3572                 goto Ldone;
3573             }
3574         }
3575 
3576         if (ClassDeclaration cd = parent.isClassDeclaration())
3577         {
3578             parent = cd = objc.getParent(funcdecl, cd);
3579 
3580             if (funcdecl.isCtorDeclaration())
3581             {
3582                 goto Ldone;
3583             }
3584 
3585             if (funcdecl.storage_class & STC.abstract_)
3586                 cd.isabstract = Abstract.yes;
3587 
3588             // if static function, do not put in vtbl[]
3589             if (!funcdecl.isVirtual())
3590             {
3591                 //printf("\tnot virtual\n");
3592                 goto Ldone;
3593             }
3594             // Suppress further errors if the return type is an error
3595             if (funcdecl.type.nextOf() == Type.terror)
3596                 goto Ldone;
3597 
3598             bool may_override = false;
3599             for (size_t i = 0; i < cd.baseclasses.dim; i++)
3600             {
3601                 BaseClass* b = (*cd.baseclasses)[i];
3602                 ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
3603                 if (!cbd)
3604                     continue;
3605                 for (size_t j = 0; j < cbd.vtbl.dim; j++)
3606                 {
3607                     FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
3608                     if (!f2 || f2.ident != funcdecl.ident)
3609                         continue;
3610                     if (cbd.parent && cbd.parent.isTemplateInstance())
3611                     {
3612                         if (!f2.functionSemantic())
3613                             goto Ldone;
3614                     }
3615                     may_override = true;
3616                 }
3617             }
3618             if (may_override && funcdecl.type.nextOf() is null)
3619             {
3620                 /* If same name function exists in base class but 'this' is auto return,
3621                  * cannot find index of base class's vtbl[] to override.
3622                  */
3623                 funcdecl.error("return type inference is not supported if may override base class function");
3624             }
3625 
3626             /* Find index of existing function in base class's vtbl[] to override
3627              * (the index will be the same as in cd's current vtbl[])
3628              */
3629             int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;
3630 
3631             bool doesoverride = false;
3632             switch (vi)
3633             {
3634             case -1:
3635             Lintro:
3636                 /* Didn't find one, so
3637                  * This is an 'introducing' function which gets a new
3638                  * slot in the vtbl[].
3639                  */
3640 
3641                 // Verify this doesn't override previous final function
3642                 if (cd.baseClass)
3643                 {
3644                     Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
3645                     if (s)
3646                     {
3647                         FuncDeclaration f2 = s.isFuncDeclaration();
3648                         if (f2)
3649                         {
3650                             f2 = f2.overloadExactMatch(funcdecl.type);
3651                             if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)
3652                                 funcdecl.error("cannot override `final` function `%s`", f2.toPrettyChars());
3653                         }
3654                     }
3655                 }
3656 
3657                 /* These quirky conditions mimic what VC++ appears to do
3658                  */
3659                 if (global.params.mscoff && cd.classKind == ClassKind.cpp &&
3660                     cd.baseClass && cd.baseClass.vtbl.dim)
3661                 {
3662                     /* if overriding an interface function, then this is not
3663                      * introducing and don't put it in the class vtbl[]
3664                      */
3665                     funcdecl.interfaceVirtual = funcdecl.overrideInterface();
3666                     if (funcdecl.interfaceVirtual)
3667                     {
3668                         //printf("\tinterface function %s\n", toChars());
3669                         cd.vtblFinal.push(funcdecl);
3670                         goto Linterfaces;
3671                     }
3672                 }
3673 
3674                 if (funcdecl.isFinalFunc())
3675                 {
3676                     // Don't check here, as it may override an interface function
3677                     //if (isOverride())
3678                     //    error("is marked as override, but does not override any function");
3679                     cd.vtblFinal.push(funcdecl);
3680                 }
3681                 else
3682                 {
3683                     //printf("\tintroducing function %s\n", funcdecl.toChars());
3684                     funcdecl.introducing = 1;
3685                     if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
3686                     {
3687                         /* Overloaded functions with same name are grouped and in reverse order.
3688                          * Search for first function of overload group, and insert
3689                          * funcdecl into vtbl[] immediately before it.
3690                          */
3691                         funcdecl.vtblIndex = cast(int)cd.vtbl.dim;
3692                         bool found;
3693                         foreach (const i, s; cd.vtbl)
3694                         {
3695                             if (found)
3696                                 // the rest get shifted forward
3697                                 ++s.isFuncDeclaration().vtblIndex;
3698                             else if (s.ident == funcdecl.ident && s.parent == parent)
3699                             {
3700                                 // found first function of overload group
3701                                 funcdecl.vtblIndex = cast(int)i;
3702                                 found = true;
3703                                 ++s.isFuncDeclaration().vtblIndex;
3704                             }
3705                         }
3706                         cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
3707 
3708                         debug foreach (const i, s; cd.vtbl)
3709                         {
3710                             // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
3711                             // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
3712                             if (auto fd = s.isFuncDeclaration())
3713                                 assert(fd.vtblIndex == i ||
3714                                        (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
3715                                        funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
3716                         }
3717                     }
3718                     else
3719                     {
3720                         // Append to end of vtbl[]
3721                         vi = cast(int)cd.vtbl.dim;
3722                         cd.vtbl.push(funcdecl);
3723                         funcdecl.vtblIndex = vi;
3724                     }
3725                 }
3726                 break;
3727 
3728             case -2:
3729                 // can't determine because of forward references
3730                 funcdecl.errors = true;
3731                 return;
3732 
3733             default:
3734                 {
3735                     FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
3736                     FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
3737                     // This function is covariant with fdv
3738 
3739                     if (fdc == funcdecl)
3740                     {
3741                         doesoverride = true;
3742                         break;
3743                     }
3744 
3745                     if (fdc.toParent() == parent)
3746                     {
3747                         //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
3748                         //        vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
3749                         //            fdc,  fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
3750                         //            fdv,  fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
3751 
3752                         // fdc overrides fdv exactly, then this introduces new function.
3753                         if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
3754                             goto Lintro;
3755                     }
3756 
3757                     if (fdv.isDeprecated)
3758                         deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
3759                                     funcdecl.toPrettyChars, fdv.toPrettyChars);
3760 
3761                     // This function overrides fdv
3762                     if (fdv.isFinalFunc())
3763                         funcdecl.error("cannot override `final` function `%s`", fdv.toPrettyChars());
3764 
3765                     if (!funcdecl.isOverride())
3766                     {
3767                         if (fdv.isFuture())
3768                         {
3769                             deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars());
3770                             // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
3771                             goto Lintro;
3772                         }
3773                         else
3774                         {
3775                             // https://issues.dlang.org/show_bug.cgi?id=17349
3776                             error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
3777                                   fdv.toPrettyChars(), funcdecl.toPrettyChars());
3778                         }
3779                     }
3780                     doesoverride = true;
3781                     if (fdc.toParent() == parent)
3782                     {
3783                         // If both are mixins, or both are not, then error.
3784                         // If either is not, the one that is not overrides the other.
3785                         bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
3786                         bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
3787                         if (thismixin == fdcmixin)
3788                         {
3789                             funcdecl.error("multiple overrides of same function");
3790                         }
3791                         /*
3792                          * https://issues.dlang.org/show_bug.cgi?id=711
3793                          *
3794                          * If an overriding method is introduced through a mixin,
3795                          * we need to update the vtbl so that both methods are
3796                          * present.
3797                          */
3798                         else if (thismixin)
3799                         {
3800                             /* if the mixin introduced the overriding method, then reintroduce it
3801                              * in the vtbl. The initial entry for the mixined method
3802                              * will be updated at the end of the enclosing `if` block
3803                              * to point to the current (non-mixined) function.
3804                              */
3805                             auto vitmp = cast(int)cd.vtbl.dim;
3806                             cd.vtbl.push(fdc);
3807                             fdc.vtblIndex = vitmp;
3808                         }
3809                         else if (fdcmixin)
3810                         {
3811                             /* if the current overriding function is coming from a
3812                              * mixined block, then push the current function in the
3813                              * vtbl, but keep the previous (non-mixined) function as
3814                              * the overriding one.
3815                              */
3816                             auto vitmp = cast(int)cd.vtbl.dim;
3817                             cd.vtbl.push(funcdecl);
3818                             funcdecl.vtblIndex = vitmp;
3819                             break;
3820                         }
3821                         else // fdc overrides fdv
3822                         {
3823                             // this doesn't override any function
3824                             break;
3825                         }
3826                     }
3827                     cd.vtbl[vi] = funcdecl;
3828                     funcdecl.vtblIndex = vi;
3829 
3830                     /* Remember which functions this overrides
3831                      */
3832                     funcdecl.foverrides.push(fdv);
3833 
3834                     /* This works by whenever this function is called,
3835                      * it actually returns tintro, which gets dynamically
3836                      * cast to type. But we know that tintro is a base
3837                      * of type, so we could optimize it by not doing a
3838                      * dynamic cast, but just subtracting the isBaseOf()
3839                      * offset if the value is != null.
3840                      */
3841 
3842                     if (fdv.tintro)
3843                         funcdecl.tintro = fdv.tintro;
3844                     else if (!funcdecl.type.equals(fdv.type))
3845                     {
3846                         /* Only need to have a tintro if the vptr
3847                          * offsets differ
3848                          */
3849                         int offset;
3850                         if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
3851                         {
3852                             funcdecl.tintro = fdv.type;
3853                         }
3854                     }
3855                     break;
3856                 }
3857             }
3858 
3859             /* Go through all the interface bases.
3860              * If this function is covariant with any members of those interface
3861              * functions, set the tintro.
3862              */
3863         Linterfaces:
3864             bool foundVtblMatch = false;
3865 
3866             foreach (b; cd.interfaces)
3867             {
3868                 vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
3869                 switch (vi)
3870                 {
3871                 case -1:
3872                     break;
3873 
3874                 case -2:
3875                     // can't determine because of forward references
3876                     funcdecl.errors = true;
3877                     return;
3878 
3879                 default:
3880                     {
3881                         auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
3882                         Type ti = null;
3883 
3884                         foundVtblMatch = true;
3885 
3886                         /* Remember which functions this overrides
3887                          */
3888                         funcdecl.foverrides.push(fdv);
3889 
3890                         /* Should we really require 'override' when implementing
3891                          * an interface function?
3892                          */
3893                         //if (!isOverride())
3894                         //    warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
3895 
3896                         if (fdv.tintro)
3897                             ti = fdv.tintro;
3898                         else if (!funcdecl.type.equals(fdv.type))
3899                         {
3900                             /* Only need to have a tintro if the vptr
3901                              * offsets differ
3902                              */
3903                             int offset;
3904                             if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
3905                             {
3906                                 ti = fdv.type;
3907                             }
3908                         }
3909                         if (ti)
3910                         {
3911                             if (funcdecl.tintro)
3912                             {
3913                                 if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
3914                                 {
3915                                     funcdecl.error("incompatible covariant types `%s` and `%s`", funcdecl.tintro.toChars(), ti.toChars());
3916                                 }
3917                             }
3918                             else
3919                             {
3920                                 funcdecl.tintro = ti;
3921                             }
3922                         }
3923                     }
3924                 }
3925             }
3926             if (foundVtblMatch)
3927             {
3928                 goto L2;
3929             }
3930 
3931             if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
3932             {
3933                 BaseClass* bc = null;
3934                 Dsymbol s = null;
3935                 for (size_t i = 0; i < cd.baseclasses.dim; i++)
3936                 {
3937                     bc = (*cd.baseclasses)[i];
3938                     s = bc.sym.search_correct(funcdecl.ident);
3939                     if (s)
3940                         break;
3941                 }
3942 
3943                 if (s)
3944                 {
3945                     HdrGenState hgs;
3946                     OutBuffer buf;
3947 
3948                     auto fd = s.isFuncDeclaration();
3949                     functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
3950                         new Identifier(funcdecl.toPrettyChars()), &hgs, null);
3951                     const(char)* funcdeclToChars = buf.peekChars();
3952 
3953                     if (fd)
3954                     {
3955                         OutBuffer buf1;
3956 
3957                         if (fd.ident == funcdecl.ident)
3958                             hgs.fullQual = true;
3959                         functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
3960                             new Identifier(fd.toPrettyChars()), &hgs, null);
3961 
3962                         error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
3963                             funcdeclToChars, buf1.peekChars());
3964                     }
3965                     else
3966                     {
3967                         error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
3968                             funcdeclToChars, s.kind, s.toPrettyChars());
3969                         errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overriden");
3970                     }
3971                 }
3972                 else
3973                     funcdecl.error("does not override any function");
3974             }
3975 
3976         L2:
3977             objc.setSelector(funcdecl, sc);
3978             objc.checkLinkage(funcdecl);
3979             objc.addToClassMethodList(funcdecl, cd);
3980 
3981             /* Go through all the interface bases.
3982              * Disallow overriding any final functions in the interface(s).
3983              */
3984             foreach (b; cd.interfaces)
3985             {
3986                 if (b.sym)
3987                 {
3988                     Dsymbol s = search_function(b.sym, funcdecl.ident);
3989                     if (s)
3990                     {
3991                         FuncDeclaration f2 = s.isFuncDeclaration();
3992                         if (f2)
3993                         {
3994                             f2 = f2.overloadExactMatch(funcdecl.type);
3995                             if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)
3996                                 funcdecl.error("cannot override `final` function `%s.%s`", b.sym.toChars(), f2.toPrettyChars());
3997                         }
3998                     }
3999                 }
4000             }
4001 
4002             if (funcdecl.isOverride)
4003             {
4004                 if (funcdecl.storage_class & STC.disable)
4005                     deprecation(funcdecl.loc,
4006                                 "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
4007                                 funcdecl.toPrettyChars);
4008                 if (funcdecl.isDeprecated)
4009                     deprecation(funcdecl.loc,
4010                                 "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
4011                                 funcdecl.toPrettyChars);
4012             }
4013 
4014         }
4015         else if (funcdecl.isOverride() && !parent.isTemplateInstance())
4016             funcdecl.error("`override` only applies to class member functions");
4017 
4018         if (auto ti = parent.isTemplateInstance)
4019             objc.setSelector(funcdecl, sc);
4020 
4021         objc.validateSelector(funcdecl);
4022         // Reflect this.type to f because it could be changed by findVtblIndex
4023         f = funcdecl.type.toTypeFunction();
4024 
4025     Ldone:
4026         if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
4027             funcdecl.error("`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract");
4028 
4029         /* Do not allow template instances to add virtual functions
4030          * to a class.
4031          */
4032         if (funcdecl.isVirtual())
4033         {
4034             TemplateInstance ti = parent.isTemplateInstance();
4035             if (ti)
4036             {
4037                 // Take care of nested templates
4038                 while (1)
4039                 {
4040                     TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
4041                     if (!ti2)
4042                         break;
4043                     ti = ti2;
4044                 }
4045 
4046                 // If it's a member template
4047                 ClassDeclaration cd = ti.tempdecl.isClassMember();
4048                 if (cd)
4049                 {
4050                     funcdecl.error("cannot use template to add virtual function to class `%s`", cd.toChars());
4051                 }
4052             }
4053         }
4054 
4055         if (funcdecl.isMain())
4056             funcdecl.checkDmain();       // Check main() parameters and return type
4057 
4058         /* Purity and safety can be inferred for some functions by examining
4059          * the function body.
4060          */
4061         if (funcdecl.canInferAttributes(sc))
4062             funcdecl.initInferAttributes();
4063 
4064         Module.dprogress++;
4065         funcdecl.semanticRun = PASS.semanticdone;
4066 
4067         /* Save scope for possible later use (if we need the
4068          * function internals)
4069          */
4070         funcdecl._scope = sc.copy();
4071         funcdecl._scope.setNoFree();
4072 
4073         __gshared bool printedMain = false; // semantic might run more than once
4074         if (global.params.verbose && !printedMain)
4075         {
4076             const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
4077             Module mod = sc._module;
4078 
4079             if (type && mod)
4080             {
4081                 printedMain = true;
4082                 auto name = mod.srcfile.toChars();
4083                 auto path = FileName.searchPath(global.path, name, true);
4084                 message("entry     %-10s\t%s", type, path ? path : name);
4085             }
4086         }
4087 
4088         if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
4089         {
4090             // check if `_d_cmain` is defined
4091             bool cmainTemplateExists()
4092             {
4093                 auto rootSymbol = sc.search(funcdecl.loc, Id.empty, null);
4094                 if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
4095                     if (moduleSymbol.search(funcdecl.loc, Id.CMain))
4096                         return true;
4097 
4098                 return false;
4099             }
4100 
4101             // Only mixin `_d_cmain` if it is defined
4102             if (cmainTemplateExists())
4103             {
4104                 // add `mixin _d_cmain!();` to the declaring module
4105                 auto tqual = Pool!TypeIdentifier.make(funcdecl.loc, Id.CMain);
4106                 auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
4107                 sc._module.members.push(tm);
4108             }
4109 
4110             rootHasMain = sc._module;
4111         }
4112 
4113         assert(funcdecl.type.ty != Terror || funcdecl.errors);
4114 
4115         // semantic for parameters' UDAs
4116         foreach (i, param; f.parameterList)
4117         {
4118             if (param && param.userAttribDecl)
4119                 param.userAttribDecl.dsymbolSemantic(sc);
4120         }
4121     }
4122 
4123      /// Do the semantic analysis on the external interface to the function.
4124     override void visit(FuncDeclaration funcdecl)
4125     {
4126         funcDeclarationSemantic(funcdecl);
4127     }
4128 
4129     override void visit(CtorDeclaration ctd)
4130     {
4131         //printf("CtorDeclaration::semantic() %s\n", toChars());
4132         if (ctd.semanticRun >= PASS.semanticdone)
4133             return;
4134         if (ctd._scope)
4135         {
4136             sc = ctd._scope;
4137             ctd._scope = null;
4138         }
4139 
4140         ctd.parent = sc.parent;
4141         Dsymbol p = ctd.toParentDecl();
4142         AggregateDeclaration ad = p.isAggregateDeclaration();
4143         if (!ad)
4144         {
4145             error(ctd.loc, "constructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4146             ctd.type = Type.terror;
4147             ctd.errors = true;
4148             return;
4149         }
4150 
4151         sc = sc.push();
4152 
4153         if (sc.stc & STC.static_)
4154         {
4155             if (sc.stc & STC.shared_)
4156                 error(ctd.loc, "`shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`");
4157             else
4158                 error(ctd.loc, "`static` has no effect on a constructor inside a `static` block. Use `static this()`");
4159         }
4160 
4161         sc.stc &= ~STC.static_; // not a static constructor
4162         sc.flags |= SCOPE.ctor;
4163 
4164         funcDeclarationSemantic(ctd);
4165 
4166         sc.pop();
4167 
4168         if (ctd.errors)
4169             return;
4170 
4171         TypeFunction tf = ctd.type.toTypeFunction();
4172 
4173         /* See if it's the default constructor
4174          * But, template constructor should not become a default constructor.
4175          */
4176         if (ad && (!ctd.parent.isTemplateInstance() || ctd.parent.isTemplateMixin()))
4177         {
4178             immutable dim = tf.parameterList.length;
4179 
4180             if (auto sd = ad.isStructDeclaration())
4181             {
4182                 if (dim == 0 && tf.parameterList.varargs == VarArg.none) // empty default ctor w/o any varargs
4183                 {
4184                     if (ctd.fbody || !(ctd.storage_class & STC.disable))
4185                     {
4186                         ctd.error("default constructor for structs only allowed " ~
4187                             "with `@disable`, no body, and no parameters");
4188                         ctd.storage_class |= STC.disable;
4189                         ctd.fbody = null;
4190                     }
4191                     sd.noDefaultCtor = true;
4192                 }
4193                 else if (dim == 0 && tf.parameterList.varargs != VarArg.none) // allow varargs only ctor
4194                 {
4195                 }
4196                 else if (dim && tf.parameterList[0].defaultArg)
4197                 {
4198                     // if the first parameter has a default argument, then the rest does as well
4199                     if (ctd.storage_class & STC.disable)
4200                     {
4201                         ctd.error("is marked `@disable`, so it cannot have default "~
4202                                   "arguments for all parameters.");
4203                         errorSupplemental(ctd.loc, "Use `@disable this();` if you want to disable default initialization.");
4204                     }
4205                     else
4206                         ctd.error("all parameters have default arguments, "~
4207                                   "but structs cannot have default constructors.");
4208                 }
4209                 else if ((dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
4210                 {
4211                     //printf("tf: %s\n", tf.toChars());
4212                     auto param = tf.parameterList[0];
4213                     if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
4214                     {
4215                         //printf("copy constructor\n");
4216                         ctd.isCpCtor = true;
4217                     }
4218                 }
4219             }
4220             else if (dim == 0 && tf.parameterList.varargs == VarArg.none)
4221             {
4222                 ad.defaultCtor = ctd;
4223             }
4224         }
4225     }
4226 
4227     override void visit(PostBlitDeclaration pbd)
4228     {
4229         //printf("PostBlitDeclaration::semantic() %s\n", toChars());
4230         //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
4231         //printf("stc = x%llx\n", sc.stc);
4232         if (pbd.semanticRun >= PASS.semanticdone)
4233             return;
4234         if (pbd._scope)
4235         {
4236             sc = pbd._scope;
4237             pbd._scope = null;
4238         }
4239 
4240         pbd.parent = sc.parent;
4241         Dsymbol p = pbd.toParent2();
4242         StructDeclaration ad = p.isStructDeclaration();
4243         if (!ad)
4244         {
4245             error(pbd.loc, "postblit can only be a member of struct, not %s `%s`", p.kind(), p.toChars());
4246             pbd.type = Type.terror;
4247             pbd.errors = true;
4248             return;
4249         }
4250         if (pbd.ident == Id.postblit && pbd.semanticRun < PASS.semantic)
4251             ad.postblits.push(pbd);
4252         if (!pbd.type)
4253             pbd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, pbd.storage_class);
4254 
4255         sc = sc.push();
4256         sc.stc &= ~STC.static_; // not static
4257         sc.linkage = LINK.d;
4258 
4259         funcDeclarationSemantic(pbd);
4260 
4261         sc.pop();
4262     }
4263 
4264     override void visit(DtorDeclaration dd)
4265     {
4266         //printf("DtorDeclaration::semantic() %s\n", toChars());
4267         //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
4268         if (dd.semanticRun >= PASS.semanticdone)
4269             return;
4270         if (dd._scope)
4271         {
4272             sc = dd._scope;
4273             dd._scope = null;
4274         }
4275 
4276         dd.parent = sc.parent;
4277         Dsymbol p = dd.toParent2();
4278         AggregateDeclaration ad = p.isAggregateDeclaration();
4279         if (!ad)
4280         {
4281             error(dd.loc, "destructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4282             dd.type = Type.terror;
4283             dd.errors = true;
4284             return;
4285         }
4286         if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)
4287             ad.dtors.push(dd);
4288         if (!dd.type)
4289         {
4290             dd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, dd.storage_class);
4291             if (ad.classKind == ClassKind.cpp && dd.ident == Id.dtor)
4292             {
4293                 if (auto cldec = ad.isClassDeclaration())
4294                 {
4295                     assert (cldec.cppDtorVtblIndex == -1); // double-call check already by dd.type
4296                     if (cldec.baseClass && cldec.baseClass.cppDtorVtblIndex != -1)
4297                     {
4298                         // override the base virtual
4299                         cldec.cppDtorVtblIndex = cldec.baseClass.cppDtorVtblIndex;
4300                     }
4301                     else if (!dd.isFinal())
4302                     {
4303                         // reserve the dtor slot for the destructor (which we'll create later)
4304                         cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;
4305                         cldec.vtbl.push(dd);
4306                         if (target.cpp.twoDtorInVtable)
4307                             cldec.vtbl.push(dd); // deleting destructor uses a second slot
4308                     }
4309                 }
4310             }
4311         }
4312 
4313         sc = sc.push();
4314         sc.stc &= ~STC.static_; // not a static destructor
4315         if (sc.linkage != LINK.cpp)
4316             sc.linkage = LINK.d;
4317 
4318         funcDeclarationSemantic(dd);
4319 
4320         sc.pop();
4321     }
4322 
4323     override void visit(StaticCtorDeclaration scd)
4324     {
4325         //printf("StaticCtorDeclaration::semantic()\n");
4326         if (scd.semanticRun >= PASS.semanticdone)
4327             return;
4328         if (scd._scope)
4329         {
4330             sc = scd._scope;
4331             scd._scope = null;
4332         }
4333 
4334         scd.parent = sc.parent;
4335         Dsymbol p = scd.parent.pastMixin();
4336         if (!p.isScopeDsymbol())
4337         {
4338             const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4339             error(scd.loc, "`%sstatic` constructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4340             scd.type = Type.terror;
4341             scd.errors = true;
4342             return;
4343         }
4344         if (!scd.type)
4345             scd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, scd.storage_class);
4346 
4347         /* If the static ctor appears within a template instantiation,
4348          * it could get called multiple times by the module constructors
4349          * for different modules. Thus, protect it with a gate.
4350          */
4351         if (scd.isInstantiated() && scd.semanticRun < PASS.semantic)
4352         {
4353             /* Add this prefix to the function:
4354              *      static int gate;
4355              *      if (++gate != 1) return;
4356              * Note that this is not thread safe; should not have threads
4357              * during static construction.
4358              */
4359             auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4360             v.storage_class = STC.temp | (scd.isSharedStaticCtorDeclaration() ? STC.static_ : STC.tls);
4361 
4362             auto sa = new Statements();
4363             Statement s = new ExpStatement(Loc.initial, v);
4364             sa.push(s);
4365 
4366             Expression e = new IdentifierExp(Loc.initial, v.ident);
4367             e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!1);
4368             e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!1);
4369             s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4370 
4371             sa.push(s);
4372             if (scd.fbody)
4373                 sa.push(scd.fbody);
4374 
4375             scd.fbody = new CompoundStatement(Loc.initial, sa);
4376         }
4377 
4378         const LINK save = sc.linkage;
4379         if (save != LINK.d)
4380         {
4381             const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4382             deprecation(scd.loc, "`%sstatic` constructor can only be of D linkage", s);
4383             // Just correct it
4384             sc.linkage = LINK.d;
4385         }
4386         funcDeclarationSemantic(scd);
4387         sc.linkage = save;
4388 
4389         // We're going to need ModuleInfo
4390         Module m = scd.getModule();
4391         if (!m)
4392             m = sc._module;
4393         if (m)
4394         {
4395             m.needmoduleinfo = 1;
4396             //printf("module1 %s needs moduleinfo\n", m.toChars());
4397         }
4398     }
4399 
4400     override void visit(StaticDtorDeclaration sdd)
4401     {
4402         if (sdd.semanticRun >= PASS.semanticdone)
4403             return;
4404         if (sdd._scope)
4405         {
4406             sc = sdd._scope;
4407             sdd._scope = null;
4408         }
4409 
4410         sdd.parent = sc.parent;
4411         Dsymbol p = sdd.parent.pastMixin();
4412         if (!p.isScopeDsymbol())
4413         {
4414             const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4415             error(sdd.loc, "`%sstatic` destructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4416             sdd.type = Type.terror;
4417             sdd.errors = true;
4418             return;
4419         }
4420         if (!sdd.type)
4421             sdd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, sdd.storage_class);
4422 
4423         /* If the static ctor appears within a template instantiation,
4424          * it could get called multiple times by the module constructors
4425          * for different modules. Thus, protect it with a gate.
4426          */
4427         if (sdd.isInstantiated() && sdd.semanticRun < PASS.semantic)
4428         {
4429             /* Add this prefix to the function:
4430              *      static int gate;
4431              *      if (--gate != 0) return;
4432              * Increment gate during constructor execution.
4433              * Note that this is not thread safe; should not have threads
4434              * during static destruction.
4435              */
4436             auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4437             v.storage_class = STC.temp | (sdd.isSharedStaticDtorDeclaration() ? STC.static_ : STC.tls);
4438 
4439             auto sa = new Statements();
4440             Statement s = new ExpStatement(Loc.initial, v);
4441             sa.push(s);
4442 
4443             Expression e = new IdentifierExp(Loc.initial, v.ident);
4444             e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!(-1));
4445             e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!0);
4446             s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4447 
4448             sa.push(s);
4449             if (sdd.fbody)
4450                 sa.push(sdd.fbody);
4451 
4452             sdd.fbody = new CompoundStatement(Loc.initial, sa);
4453 
4454             sdd.vgate = v;
4455         }
4456 
4457         const LINK save = sc.linkage;
4458         if (save != LINK.d)
4459         {
4460             const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4461             deprecation(sdd.loc, "`%sstatic` destructor can only be of D linkage", s);
4462             // Just correct it
4463             sc.linkage = LINK.d;
4464         }
4465         funcDeclarationSemantic(sdd);
4466         sc.linkage = save;
4467 
4468         // We're going to need ModuleInfo
4469         Module m = sdd.getModule();
4470         if (!m)
4471             m = sc._module;
4472         if (m)
4473         {
4474             m.needmoduleinfo = 1;
4475             //printf("module2 %s needs moduleinfo\n", m.toChars());
4476         }
4477     }
4478 
4479     override void visit(InvariantDeclaration invd)
4480     {
4481         if (invd.semanticRun >= PASS.semanticdone)
4482             return;
4483         if (invd._scope)
4484         {
4485             sc = invd._scope;
4486             invd._scope = null;
4487         }
4488 
4489         invd.parent = sc.parent;
4490         Dsymbol p = invd.parent.pastMixin();
4491         AggregateDeclaration ad = p.isAggregateDeclaration();
4492         if (!ad)
4493         {
4494             error(invd.loc, "`invariant` can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4495             invd.type = Type.terror;
4496             invd.errors = true;
4497             return;
4498         }
4499         if (invd.ident != Id.classInvariant &&
4500              invd.semanticRun < PASS.semantic &&
4501              !ad.isUnionDeclaration()           // users are on their own with union fields
4502            )
4503             ad.invs.push(invd);
4504         if (!invd.type)
4505             invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class);
4506 
4507         sc = sc.push();
4508         sc.stc &= ~STC.static_; // not a static invariant
4509         sc.stc |= STC.const_; // invariant() is always const
4510         sc.flags = (sc.flags & ~SCOPE.contract) | SCOPE.invariant_;
4511         sc.linkage = LINK.d;
4512 
4513         funcDeclarationSemantic(invd);
4514 
4515         sc.pop();
4516     }
4517 
4518     override void visit(UnitTestDeclaration utd)
4519     {
4520         if (utd.semanticRun >= PASS.semanticdone)
4521             return;
4522         if (utd._scope)
4523         {
4524             sc = utd._scope;
4525             utd._scope = null;
4526         }
4527 
4528         utd.protection = sc.protection;
4529 
4530         utd.parent = sc.parent;
4531         Dsymbol p = utd.parent.pastMixin();
4532         if (!p.isScopeDsymbol())
4533         {
4534             error(utd.loc, "`unittest` can only be a member of module/aggregate/template, not %s `%s`", p.kind(), p.toChars());
4535             utd.type = Type.terror;
4536             utd.errors = true;
4537             return;
4538         }
4539 
4540         if (global.params.useUnitTests)
4541         {
4542             if (!utd.type)
4543                 utd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, utd.storage_class);
4544             Scope* sc2 = sc.push();
4545             sc2.linkage = LINK.d;
4546             funcDeclarationSemantic(utd);
4547             sc2.pop();
4548         }
4549 
4550         version (none)
4551         {
4552             // We're going to need ModuleInfo even if the unit tests are not
4553             // compiled in, because other modules may import this module and refer
4554             // to this ModuleInfo.
4555             // (This doesn't make sense to me?)
4556             Module m = utd.getModule();
4557             if (!m)
4558                 m = sc._module;
4559             if (m)
4560             {
4561                 //printf("module3 %s needs moduleinfo\n", m.toChars());
4562                 m.needmoduleinfo = 1;
4563             }
4564         }
4565     }
4566 
4567     override void visit(NewDeclaration nd)
4568     {
4569         //printf("NewDeclaration::semantic()\n");
4570 
4571         // `@disable new();` should not be deprecated
4572         if (!nd.isDisabled())
4573         {
4574             // @@@DEPRECATED_2.091@@@
4575             // Made an error in 2.087.
4576             // Should be removed in 2.091
4577             error(nd.loc, "class allocators are obsolete, consider moving the allocation strategy outside of the class");
4578         }
4579 
4580         if (nd.semanticRun >= PASS.semanticdone)
4581             return;
4582         if (nd._scope)
4583         {
4584             sc = nd._scope;
4585             nd._scope = null;
4586         }
4587 
4588         nd.parent = sc.parent;
4589         Dsymbol p = nd.parent.pastMixin();
4590         if (!p.isAggregateDeclaration())
4591         {
4592             error(nd.loc, "allocator can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4593             nd.type = Type.terror;
4594             nd.errors = true;
4595             return;
4596         }
4597         Type tret = Type.tvoid.pointerTo();
4598         if (!nd.type)
4599             nd.type = new TypeFunction(nd.parameterList, tret, LINK.d, nd.storage_class);
4600 
4601         nd.type = nd.type.typeSemantic(nd.loc, sc);
4602 
4603         // allow for `@disable new();` to force users of a type to use an external allocation strategy
4604         if (!nd.isDisabled())
4605         {
4606             // Check that there is at least one argument of type size_t
4607             TypeFunction tf = nd.type.toTypeFunction();
4608             if (tf.parameterList.length < 1)
4609             {
4610                 nd.error("at least one argument of type `size_t` expected");
4611             }
4612             else
4613             {
4614                 Parameter fparam = tf.parameterList[0];
4615                 if (!fparam.type.equals(Type.tsize_t))
4616                     nd.error("first argument must be type `size_t`, not `%s`", fparam.type.toChars());
4617             }
4618         }
4619 
4620         funcDeclarationSemantic(nd);
4621     }
4622 
4623     /* https://issues.dlang.org/show_bug.cgi?id=19731
4624      *
4625      * Some aggregate member functions might have had
4626      * semantic 3 ran on them despite being in semantic1
4627      * (e.g. auto functions); if that is the case, then
4628      * invariants will not be taken into account for them
4629      * because at the time of the analysis it would appear
4630      * as if the struct declaration does not have any
4631      * invariants. To solve this issue, we need to redo
4632      * semantic3 on the function declaration.
4633      */
4634     private void reinforceInvariant(AggregateDeclaration ad, Scope* sc)
4635     {
4636         // for each member
4637         for(int i = 0; i < ad.members.dim; i++)
4638         {
4639             if (!(*ad.members)[i])
4640                 continue;
4641             auto fd = (*ad.members)[i].isFuncDeclaration();
4642             if (!fd || fd.generated || fd.semanticRun != PASS.semantic3done)
4643                 continue;
4644 
4645             /* if it's a user defined function declaration and semantic3
4646              * was already performed on it, create a syntax copy and
4647              * redo the first semantic step.
4648              */
4649             auto fd_temp = fd.syntaxCopy(null).isFuncDeclaration();
4650             fd_temp.storage_class &= ~STC.auto_; // type has already been inferred
4651             if (auto cd = ad.isClassDeclaration())
4652                 cd.vtbl.remove(fd.vtblIndex);
4653             fd_temp.dsymbolSemantic(sc);
4654             (*ad.members)[i] = fd_temp;
4655         }
4656     }
4657 
4658     override void visit(StructDeclaration sd)
4659     {
4660         //printf("StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4661 
4662         //static int count; if (++count == 20) assert(0);
4663 
4664         if (sd.semanticRun >= PASS.semanticdone)
4665             return;
4666         int errors = global.errors;
4667 
4668         //printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", this, toPrettyChars(), sizeok);
4669         Scope* scx = null;
4670         if (sd._scope)
4671         {
4672             sc = sd._scope;
4673             scx = sd._scope; // save so we don't make redundant copies
4674             sd._scope = null;
4675         }
4676 
4677         if (!sd.parent)
4678         {
4679             assert(sc.parent && sc.func);
4680             sd.parent = sc.parent;
4681         }
4682         assert(sd.parent && !sd.isAnonymous());
4683 
4684         if (sd.errors)
4685             sd.type = Type.terror;
4686         if (sd.semanticRun == PASS.init)
4687             sd.type = sd.type.addSTC(sc.stc | sd.storage_class);
4688         sd.type = sd.type.typeSemantic(sd.loc, sc);
4689         if (auto ts = sd.type.isTypeStruct())
4690             if (ts.sym != sd)
4691             {
4692                 auto ti = ts.sym.isInstantiated();
4693                 if (ti && isError(ti))
4694                     ts.sym = sd;
4695             }
4696 
4697         // Ungag errors when not speculative
4698         Ungag ungag = sd.ungagSpeculative();
4699 
4700         if (sd.semanticRun == PASS.init)
4701         {
4702             sd.protection = sc.protection;
4703 
4704             sd.alignment = sc.alignment();
4705 
4706             sd.storage_class |= sc.stc;
4707             if (sd.storage_class & STC.abstract_)
4708                 sd.error("structs, unions cannot be `abstract`");
4709 
4710             sd.userAttribDecl = sc.userAttribDecl;
4711 
4712             if (sc.linkage == LINK.cpp)
4713                 sd.classKind = ClassKind.cpp;
4714             sd.cppnamespace = sc.namespace;
4715             sd.cppmangle = sc.cppmangle;
4716         }
4717         else if (sd.symtab && !scx)
4718             return;
4719 
4720         sd.semanticRun = PASS.semantic;
4721         UserAttributeDeclaration.checkGNUABITag(sd, sc.linkage);
4722 
4723         if (!sd.members) // if opaque declaration
4724         {
4725             sd.semanticRun = PASS.semanticdone;
4726             return;
4727         }
4728         if (!sd.symtab)
4729         {
4730             sd.symtab = new DsymbolTable();
4731 
4732             sd.members.foreachDsymbol( s => s.addMember(sc, sd) );
4733         }
4734 
4735         auto sc2 = sd.newScope(sc);
4736 
4737         /* Set scope so if there are forward references, we still might be able to
4738          * resolve individual members like enums.
4739          */
4740         sd.members.foreachDsymbol( s => s.setScope(sc2) );
4741         sd.members.foreachDsymbol( s => s.importAll(sc2) );
4742         sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); sd.errors |= s.errors; } );
4743 
4744         if (sd.errors)
4745             sd.type = Type.terror;
4746 
4747         if (!sd.determineFields())
4748         {
4749             if (sd.type.ty != Terror)
4750             {
4751                 sd.error(sd.loc, "circular or forward reference");
4752                 sd.errors = true;
4753                 sd.type = Type.terror;
4754             }
4755 
4756             sc2.pop();
4757             sd.semanticRun = PASS.semanticdone;
4758             return;
4759         }
4760         /* Following special member functions creation needs semantic analysis
4761          * completion of sub-structs in each field types. For example, buildDtor
4762          * needs to check existence of elaborate dtor in type of each fields.
4763          * See the case in compilable/test14838.d
4764          */
4765         foreach (v; sd.fields)
4766         {
4767             Type tb = v.type.baseElemOf();
4768             if (tb.ty != Tstruct)
4769                 continue;
4770             auto sdec = (cast(TypeStruct)tb).sym;
4771             if (sdec.semanticRun >= PASS.semanticdone)
4772                 continue;
4773 
4774             sc2.pop();
4775 
4776             //printf("\tdeferring %s\n", toChars());
4777             return deferDsymbolSemantic(sd, scx);
4778         }
4779 
4780         /* Look for special member functions.
4781          */
4782         sd.aggNew = cast(NewDeclaration)sd.search(Loc.initial, Id.classNew);
4783 
4784         // Look for the constructor
4785         sd.ctor = sd.searchCtor();
4786 
4787         sd.dtor = buildDtor(sd, sc2);
4788         sd.tidtor = buildExternDDtor(sd, sc2);
4789         sd.postblit = buildPostBlit(sd, sc2);
4790         sd.hasCopyCtor = buildCopyCtor(sd, sc2);
4791 
4792         buildOpAssign(sd, sc2);
4793         buildOpEquals(sd, sc2);
4794 
4795         if (global.params.useTypeInfo && Type.dtypeinfo)  // these functions are used for TypeInfo
4796         {
4797             sd.xeq = buildXopEquals(sd, sc2);
4798             sd.xcmp = buildXopCmp(sd, sc2);
4799             sd.xhash = buildXtoHash(sd, sc2);
4800         }
4801 
4802         sd.inv = buildInv(sd, sc2);
4803         if (sd.inv)
4804             reinforceInvariant(sd, sc2);
4805 
4806         Module.dprogress++;
4807         sd.semanticRun = PASS.semanticdone;
4808         //printf("-StructDeclaration::semantic(this=%p, '%s')\n", sd, sd.toChars());
4809 
4810         sc2.pop();
4811 
4812         if (sd.ctor)
4813         {
4814             Dsymbol scall = sd.search(Loc.initial, Id.call);
4815             if (scall)
4816             {
4817                 uint xerrors = global.startGagging();
4818                 sc = sc.push();
4819                 sc.tinst = null;
4820                 sc.minst = null;
4821                 auto fcall = resolveFuncCall(sd.loc, sc, scall, null, null, null, FuncResolveFlag.quiet);
4822                 sc = sc.pop();
4823                 global.endGagging(xerrors);
4824 
4825                 if (fcall && fcall.isStatic())
4826                 {
4827                     sd.error(fcall.loc, "`static opCall` is hidden by constructors and can never be called");
4828                     errorSupplemental(fcall.loc, "Please use a factory method instead, or replace all constructors with `static opCall`.");
4829                 }
4830             }
4831         }
4832 
4833         if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd)
4834         {
4835             // https://issues.dlang.org/show_bug.cgi?id=19024
4836             StructDeclaration sym = (cast(TypeStruct)sd.type).sym;
4837             version (none)
4838             {
4839                 printf("this = %p %s\n", sd, sd.toChars());
4840                 printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars());
4841             }
4842             sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars());
4843         }
4844 
4845         if (global.errors != errors)
4846         {
4847             // The type is no good.
4848             sd.type = Type.terror;
4849             sd.errors = true;
4850             if (sd.deferred)
4851                 sd.deferred.errors = true;
4852         }
4853 
4854         if (sd.deferred && !global.gag)
4855         {
4856             sd.deferred.semantic2(sc);
4857             sd.deferred.semantic3(sc);
4858         }
4859     }
4860 
4861     void interfaceSemantic(ClassDeclaration cd)
4862     {
4863         cd.vtblInterfaces = new BaseClasses();
4864         cd.vtblInterfaces.reserve(cd.interfaces.length);
4865         foreach (b; cd.interfaces)
4866         {
4867             cd.vtblInterfaces.push(b);
4868             b.copyBaseInterfaces(cd.vtblInterfaces);
4869         }
4870     }
4871 
4872     override void visit(ClassDeclaration cldec)
4873     {
4874         /// Checks that the given class implements all methods of its interfaces.
4875         static void checkInterfaceImplementations(ClassDeclaration cd)
4876         {
4877             foreach (base; cd.interfaces)
4878             {
4879                 // first entry is ClassInfo reference
4880                 auto methods = base.sym.vtbl[base.sym.vtblOffset .. $];
4881 
4882                 foreach (m; methods)
4883                 {
4884                     auto ifd = m.isFuncDeclaration;
4885                     assert(ifd);
4886 
4887                     auto type = ifd.type.toTypeFunction();
4888                     auto fd = cd.findFunc(ifd.ident, type);
4889 
4890                     if (fd && !fd.isAbstract)
4891                     {
4892                         //printf("            found\n");
4893                         // Check that calling conventions match
4894                         if (fd.linkage != ifd.linkage)
4895                             fd.error("linkage doesn't match interface function");
4896 
4897                         // Check that it is current
4898                         //printf("newinstance = %d fd.toParent() = %s ifd.toParent() = %s\n",
4899                             //newinstance, fd.toParent().toChars(), ifd.toParent().toChars());
4900                         if (fd.toParent() != cd && ifd.toParent() == base.sym)
4901                             cd.error("interface function `%s` is not implemented", ifd.toFullSignature());
4902                     }
4903 
4904                     else
4905                     {
4906                         //printf("            not found %p\n", fd);
4907                         // BUG: should mark this class as abstract?
4908                         if (!cd.isAbstract())
4909                             cd.error("interface function `%s` is not implemented", ifd.toFullSignature());
4910                     }
4911                 }
4912             }
4913         }
4914 
4915         //printf("ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", cldec.toChars(), cldec.type, cldec.sizeok, this);
4916         //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : "");
4917         //printf("sc.stc = %x\n", sc.stc);
4918 
4919         //{ static int n;  if (++n == 20) *(char*)0=0; }
4920 
4921         if (cldec.semanticRun >= PASS.semanticdone)
4922             return;
4923         int errors = global.errors;
4924 
4925         //printf("+ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
4926 
4927         Scope* scx = null;
4928         if (cldec._scope)
4929         {
4930             sc = cldec._scope;
4931             scx = cldec._scope; // save so we don't make redundant copies
4932             cldec._scope = null;
4933         }
4934 
4935         if (!cldec.parent)
4936         {
4937             assert(sc.parent);
4938             cldec.parent = sc.parent;
4939         }
4940 
4941         if (cldec.errors)
4942             cldec.type = Type.terror;
4943         cldec.type = cldec.type.typeSemantic(cldec.loc, sc);
4944         if (auto tc = cldec.type.isTypeClass())
4945             if (tc.sym != cldec)
4946             {
4947                 auto ti = tc.sym.isInstantiated();
4948                 if (ti && isError(ti))
4949                     tc.sym = cldec;
4950             }
4951 
4952         // Ungag errors when not speculative
4953         Ungag ungag = cldec.ungagSpeculative();
4954 
4955         if (cldec.semanticRun == PASS.init)
4956         {
4957             cldec.protection = sc.protection;
4958 
4959             cldec.storage_class |= sc.stc;
4960             if (cldec.storage_class & STC.auto_)
4961                 cldec.error("storage class `auto` is invalid when declaring a class, did you mean to use `scope`?");
4962             if (cldec.storage_class & STC.scope_)
4963                 cldec.stack = true;
4964             if (cldec.storage_class & STC.abstract_)
4965                 cldec.isabstract = Abstract.yes;
4966 
4967             cldec.userAttribDecl = sc.userAttribDecl;
4968 
4969             if (sc.linkage == LINK.cpp)
4970                 cldec.classKind = ClassKind.cpp;
4971             cldec.cppnamespace = sc.namespace;
4972             cldec.cppmangle = sc.cppmangle;
4973             if (sc.linkage == LINK.objc)
4974                 objc.setObjc(cldec);
4975         }
4976         else if (cldec.symtab && !scx)
4977         {
4978             return;
4979         }
4980         cldec.semanticRun = PASS.semantic;
4981         UserAttributeDeclaration.checkGNUABITag(cldec, sc.linkage);
4982 
4983         if (cldec.baseok < Baseok.done)
4984         {
4985             /* https://issues.dlang.org/show_bug.cgi?id=12078
4986              * https://issues.dlang.org/show_bug.cgi?id=12143
4987              * https://issues.dlang.org/show_bug.cgi?id=15733
4988              * While resolving base classes and interfaces, a base may refer
4989              * the member of this derived class. In that time, if all bases of
4990              * this class can  be determined, we can go forward the semantc process
4991              * beyond the Lancestorsdone. To do the recursive semantic analysis,
4992              * temporarily set and unset `_scope` around exp().
4993              */
4994             T resolveBase(T)(lazy T exp)
4995             {
4996                 if (!scx)
4997                 {
4998                     scx = sc.copy();
4999                     scx.setNoFree();
5000                 }
5001                 static if (!is(T == void))
5002                 {
5003                     cldec._scope = scx;
5004                     auto r = exp();
5005                     cldec._scope = null;
5006                     return r;
5007                 }
5008                 else
5009                 {
5010                     cldec._scope = scx;
5011                     exp();
5012                     cldec._scope = null;
5013                 }
5014             }
5015 
5016             cldec.baseok = Baseok.start;
5017 
5018             // Expand any tuples in baseclasses[]
5019             for (size_t i = 0; i < cldec.baseclasses.dim;)
5020             {
5021                 auto b = (*cldec.baseclasses)[i];
5022                 b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));
5023 
5024                 Type tb = b.type.toBasetype();
5025                 if (auto tup = tb.isTypeTuple())
5026                 {
5027                     cldec.baseclasses.remove(i);
5028                     size_t dim = Parameter.dim(tup.arguments);
5029                     for (size_t j = 0; j < dim; j++)
5030                     {
5031                         Parameter arg = Parameter.getNth(tup.arguments, j);
5032                         b = new BaseClass(arg.type);
5033                         cldec.baseclasses.insert(i + j, b);
5034                     }
5035                 }
5036                 else
5037                     i++;
5038             }
5039 
5040             if (cldec.baseok >= Baseok.done)
5041             {
5042                 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
5043                 if (cldec.semanticRun >= PASS.semanticdone)
5044                     return;
5045                 goto Lancestorsdone;
5046             }
5047 
5048             // See if there's a base class as first in baseclasses[]
5049             if (cldec.baseclasses.dim)
5050             {
5051                 BaseClass* b = (*cldec.baseclasses)[0];
5052                 Type tb = b.type.toBasetype();
5053                 TypeClass tc = tb.isTypeClass();
5054                 if (!tc)
5055                 {
5056                     if (b.type != Type.terror)
5057                         cldec.error("base type must be `class` or `interface`, not `%s`", b.type.toChars());
5058                     cldec.baseclasses.remove(0);
5059                     goto L7;
5060                 }
5061                 if (tc.sym.isDeprecated())
5062                 {
5063                     if (!cldec.isDeprecated())
5064                     {
5065                         // Deriving from deprecated class makes this one deprecated too
5066                         cldec.setDeprecated();
5067                         tc.checkDeprecated(cldec.loc, sc);
5068                     }
5069                 }
5070                 if (tc.sym.isInterfaceDeclaration())
5071                     goto L7;
5072 
5073                 for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass)
5074                 {
5075                     if (cdb == cldec)
5076                     {
5077                         cldec.error("circular inheritance");
5078                         cldec.baseclasses.remove(0);
5079                         goto L7;
5080                     }
5081                 }
5082 
5083                 /* https://issues.dlang.org/show_bug.cgi?id=11034
5084                  * Class inheritance hierarchy
5085                  * and instance size of each classes are orthogonal information.
5086                  * Therefore, even if tc.sym.sizeof == Sizeok.none,
5087                  * we need to set baseClass field for class covariance check.
5088                  */
5089                 cldec.baseClass = tc.sym;
5090                 b.sym = cldec.baseClass;
5091 
5092                 if (tc.sym.baseok < Baseok.done)
5093                     resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5094                 if (tc.sym.baseok < Baseok.done)
5095                 {
5096                     //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars());
5097                     if (tc.sym._scope)
5098                         Module.addDeferredSemantic(tc.sym);
5099                     cldec.baseok = Baseok.none;
5100                 }
5101             L7:
5102             }
5103 
5104             // Treat the remaining entries in baseclasses as interfaces
5105             // Check for errors, handle forward references
5106             bool multiClassError = false;
5107 
5108             BCLoop:
5109             for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.dim;)
5110             {
5111                 BaseClass* b = (*cldec.baseclasses)[i];
5112                 Type tb = b.type.toBasetype();
5113                 TypeClass tc = tb.isTypeClass();
5114                 if (!tc || !tc.sym.isInterfaceDeclaration())
5115                 {
5116                     // It's a class
5117                     if (tc)
5118                     {
5119                         if (!multiClassError)
5120                         {
5121                             error(cldec.loc,"`%s`: multiple class inheritance is not supported." ~
5122                                   " Use multiple interface inheritance and/or composition.", cldec.toPrettyChars());
5123                             multiClassError = true;
5124                         }
5125 
5126                         if (tc.sym.fields.dim)
5127                             errorSupplemental(cldec.loc,"`%s` has fields, consider making it a member of `%s`",
5128                                               b.type.toChars(), cldec.type.toChars());
5129                         else
5130                             errorSupplemental(cldec.loc,"`%s` has no fields, consider making it an `interface`",
5131                                               b.type.toChars());
5132                     }
5133                     // It's something else: e.g. `int` in `class Foo : Bar, int { ... }`
5134                     else if (b.type != Type.terror)
5135                     {
5136                         error(cldec.loc,"`%s`: base type must be `interface`, not `%s`",
5137                               cldec.toPrettyChars(), b.type.toChars());
5138                     }
5139                     cldec.baseclasses.remove(i);
5140                     continue;
5141                 }
5142 
5143                 // Check for duplicate interfaces
5144                 for (size_t j = (cldec.baseClass ? 1 : 0); j < i; j++)
5145                 {
5146                     BaseClass* b2 = (*cldec.baseclasses)[j];
5147                     if (b2.sym == tc.sym)
5148                     {
5149                         cldec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
5150                         cldec.baseclasses.remove(i);
5151                         continue BCLoop;
5152                     }
5153                 }
5154                 if (tc.sym.isDeprecated())
5155                 {
5156                     if (!cldec.isDeprecated())
5157                     {
5158                         // Deriving from deprecated class makes this one deprecated too
5159                         cldec.setDeprecated();
5160                         tc.checkDeprecated(cldec.loc, sc);
5161                     }
5162                 }
5163 
5164                 b.sym = tc.sym;
5165 
5166                 if (tc.sym.baseok < Baseok.done)
5167                     resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5168                 if (tc.sym.baseok < Baseok.done)
5169                 {
5170                     //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
5171                     if (tc.sym._scope)
5172                         Module.addDeferredSemantic(tc.sym);
5173                     cldec.baseok = Baseok.none;
5174                 }
5175                 i++;
5176             }
5177             if (cldec.baseok == Baseok.none)
5178             {
5179                 // Forward referencee of one or more bases, try again later
5180                 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
5181                 return deferDsymbolSemantic(cldec, scx);
5182             }
5183             cldec.baseok = Baseok.done;
5184 
5185             if (cldec.classKind == ClassKind.objc || (cldec.baseClass && cldec.baseClass.classKind == ClassKind.objc))
5186                 cldec.classKind = ClassKind.objc; // Objective-C classes do not inherit from Object
5187 
5188             // If no base class, and this is not an Object, use Object as base class
5189             if (!cldec.baseClass && cldec.ident != Id.Object && cldec.object && cldec.classKind == ClassKind.d)
5190             {
5191                 void badObjectDotD()
5192                 {
5193                     cldec.error("missing or corrupt object.d");
5194                     fatal();
5195                 }
5196 
5197                 if (!cldec.object || cldec.object.errors)
5198                     badObjectDotD();
5199 
5200                 Type t = cldec.object.type;
5201                 t = t.typeSemantic(cldec.loc, sc).toBasetype();
5202                 if (t.ty == Terror)
5203                     badObjectDotD();
5204                 TypeClass tc = t.isTypeClass();
5205                 assert(tc);
5206 
5207                 auto b = new BaseClass(tc);
5208                 cldec.baseclasses.shift(b);
5209 
5210                 cldec.baseClass = tc.sym;
5211                 assert(!cldec.baseClass.isInterfaceDeclaration());
5212                 b.sym = cldec.baseClass;
5213             }
5214             if (cldec.baseClass)
5215             {
5216                 if (cldec.baseClass.storage_class & STC.final_)
5217                     cldec.error("cannot inherit from class `%s` because it is `final`", cldec.baseClass.toChars());
5218 
5219                 // Inherit properties from base class
5220                 if (cldec.baseClass.isCOMclass())
5221                     cldec.com = true;
5222                 if (cldec.baseClass.isCPPclass())
5223                     cldec.classKind = ClassKind.cpp;
5224                 if (cldec.baseClass.stack)
5225                     cldec.stack = true;
5226                 cldec.enclosing = cldec.baseClass.enclosing;
5227                 cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;
5228             }
5229 
5230             cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.dim];
5231             foreach (b; cldec.interfaces)
5232             {
5233                 // If this is an interface, and it derives from a COM interface,
5234                 // then this is a COM interface too.
5235                 if (b.sym.isCOMinterface())
5236                     cldec.com = true;
5237                 if (cldec.classKind == ClassKind.cpp && !b.sym.isCPPinterface())
5238                 {
5239                     error(cldec.loc, "C++ class `%s` cannot implement D interface `%s`",
5240                         cldec.toPrettyChars(), b.sym.toPrettyChars());
5241                 }
5242             }
5243             interfaceSemantic(cldec);
5244         }
5245     Lancestorsdone:
5246         //printf("\tClassDeclaration.dsymbolSemantic(%s) baseok = %d\n", toChars(), baseok);
5247 
5248         if (!cldec.members) // if opaque declaration
5249         {
5250             cldec.semanticRun = PASS.semanticdone;
5251             return;
5252         }
5253         if (!cldec.symtab)
5254         {
5255             cldec.symtab = new DsymbolTable();
5256 
5257             /* https://issues.dlang.org/show_bug.cgi?id=12152
5258              * The semantic analysis of base classes should be finished
5259              * before the members semantic analysis of this class, in order to determine
5260              * vtbl in this class. However if a base class refers the member of this class,
5261              * it can be resolved as a normal forward reference.
5262              * Call addMember() and setScope() to make this class members visible from the base classes.
5263              */
5264             cldec.members.foreachDsymbol( s => s.addMember(sc, cldec) );
5265 
5266             auto sc2 = cldec.newScope(sc);
5267 
5268             /* Set scope so if there are forward references, we still might be able to
5269              * resolve individual members like enums.
5270              */
5271             cldec.members.foreachDsymbol( s => s.setScope(sc2) );
5272 
5273             sc2.pop();
5274         }
5275 
5276         for (size_t i = 0; i < cldec.baseclasses.dim; i++)
5277         {
5278             BaseClass* b = (*cldec.baseclasses)[i];
5279             Type tb = b.type.toBasetype();
5280             TypeClass tc = tb.isTypeClass();
5281             if (tc.sym.semanticRun < PASS.semanticdone)
5282             {
5283                 // Forward referencee of one or more bases, try again later
5284                 if (tc.sym._scope)
5285                     Module.addDeferredSemantic(tc.sym);
5286                 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
5287                 return deferDsymbolSemantic(cldec, scx);
5288             }
5289         }
5290 
5291         if (cldec.baseok == Baseok.done)
5292         {
5293             cldec.baseok = Baseok.semanticdone;
5294             objc.setMetaclass(cldec, sc);
5295 
5296             // initialize vtbl
5297             if (cldec.baseClass)
5298             {
5299                 if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.dim == 0)
5300                 {
5301                     cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars());
5302                 }
5303 
5304                 // Copy vtbl[] from base class
5305                 cldec.vtbl.setDim(cldec.baseClass.vtbl.dim);
5306                 memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.dim);
5307 
5308                 cldec.vthis = cldec.baseClass.vthis;
5309                 cldec.vthis2 = cldec.baseClass.vthis2;
5310             }
5311             else
5312             {
5313                 // No base class, so this is the root of the class hierarchy
5314                 cldec.vtbl.setDim(0);
5315                 if (cldec.vtblOffset())
5316                     cldec.vtbl.push(cldec); // leave room for classinfo as first member
5317             }
5318 
5319             /* If this is a nested class, add the hidden 'this'
5320              * member which is a pointer to the enclosing scope.
5321              */
5322             if (cldec.vthis) // if inheriting from nested class
5323             {
5324                 // Use the base class's 'this' member
5325                 if (cldec.storage_class & STC.static_)
5326                     cldec.error("static class cannot inherit from nested class `%s`", cldec.baseClass.toChars());
5327                 if (cldec.toParentLocal() != cldec.baseClass.toParentLocal() &&
5328                     (!cldec.toParentLocal() ||
5329                      !cldec.baseClass.toParentLocal().getType() ||
5330                      !cldec.baseClass.toParentLocal().getType().isBaseOf(cldec.toParentLocal().getType(), null)))
5331                 {
5332                     if (cldec.toParentLocal())
5333                     {
5334                         cldec.error("is nested within `%s`, but super class `%s` is nested within `%s`",
5335                             cldec.toParentLocal().toChars(),
5336                             cldec.baseClass.toChars(),
5337                             cldec.baseClass.toParentLocal().toChars());
5338                     }
5339                     else
5340                     {
5341                         cldec.error("is not nested, but super class `%s` is nested within `%s`",
5342                             cldec.baseClass.toChars(),
5343                             cldec.baseClass.toParentLocal().toChars());
5344                     }
5345                     cldec.enclosing = null;
5346                 }
5347                 if (cldec.vthis2)
5348                 {
5349                     if (cldec.toParent2() != cldec.baseClass.toParent2() &&
5350                         (!cldec.toParent2() ||
5351                          !cldec.baseClass.toParent2().getType() ||
5352                          !cldec.baseClass.toParent2().getType().isBaseOf(cldec.toParent2().getType(), null)))
5353                     {
5354                         if (cldec.toParent2() && cldec.toParent2() != cldec.toParentLocal())
5355                         {
5356                             cldec.error("needs the frame pointer of `%s`, but super class `%s` needs the frame pointer of `%s`",
5357                                 cldec.toParent2().toChars(),
5358                                 cldec.baseClass.toChars(),
5359                                 cldec.baseClass.toParent2().toChars());
5360                         }
5361                         else
5362                         {
5363                             cldec.error("doesn't need a frame pointer, but super class `%s` needs the frame pointer of `%s`",
5364                                 cldec.baseClass.toChars(),
5365                                 cldec.baseClass.toParent2().toChars());
5366                         }
5367                     }
5368                 }
5369                 else
5370                     cldec.makeNested2();
5371             }
5372             else
5373                 cldec.makeNested();
5374         }
5375 
5376         auto sc2 = cldec.newScope(sc);
5377 
5378         cldec.members.foreachDsymbol( s => s.importAll(sc2) );
5379 
5380         // Note that members.dim can grow due to tuple expansion during semantic()
5381         cldec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
5382 
5383         if (!cldec.determineFields())
5384         {
5385             assert(cldec.type == Type.terror);
5386             sc2.pop();
5387             return;
5388         }
5389         /* Following special member functions creation needs semantic analysis
5390          * completion of sub-structs in each field types.
5391          */
5392         foreach (v; cldec.fields)
5393         {
5394             Type tb = v.type.baseElemOf();
5395             if (tb.ty != Tstruct)
5396                 continue;
5397             auto sd = (cast(TypeStruct)tb).sym;
5398             if (sd.semanticRun >= PASS.semanticdone)
5399                 continue;
5400 
5401             sc2.pop();
5402 
5403             //printf("\tdeferring %s\n", toChars());
5404             return deferDsymbolSemantic(cldec, scx);
5405         }
5406 
5407         /* Look for special member functions.
5408          * They must be in this class, not in a base class.
5409          */
5410         // Can be in base class
5411         cldec.aggNew = cast(NewDeclaration)cldec.search(Loc.initial, Id.classNew);
5412 
5413         // Look for the constructor
5414         cldec.ctor = cldec.searchCtor();
5415 
5416         if (!cldec.ctor && cldec.noDefaultCtor)
5417         {
5418             // A class object is always created by constructor, so this check is legitimate.
5419             foreach (v; cldec.fields)
5420             {
5421                 if (v.storage_class & STC.nodefaultctor)
5422                     error(v.loc, "field `%s` must be initialized in constructor", v.toChars());
5423             }
5424         }
5425 
5426         // If this class has no constructor, but base class has a default
5427         // ctor, create a constructor:
5428         //    this() { }
5429         if (!cldec.ctor && cldec.baseClass && cldec.baseClass.ctor)
5430         {
5431             auto fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type, null, FuncResolveFlag.quiet);
5432             if (!fd) // try shared base ctor instead
5433                 fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type.sharedOf, null, FuncResolveFlag.quiet);
5434             if (fd && !fd.errors)
5435             {
5436                 //printf("Creating default this(){} for class %s\n", toChars());
5437                 auto btf = fd.type.toTypeFunction();
5438                 auto tf = new TypeFunction(ParameterList(), null, LINK.d, fd.storage_class);
5439                 tf.mod = btf.mod;
5440                 // Don't copy @safe, ... from the base class constructor and let it be inferred instead
5441                 // This is required if other lowerings add code to the generated constructor which
5442                 // is less strict (e.g. `preview=dtorfields` might introduce a call to a less qualified dtor)
5443 
5444                 auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf);
5445                 ctor.storage_class |= STC.inference;
5446                 ctor.generated = true;
5447                 ctor.fbody = new CompoundStatement(Loc.initial, new Statements());
5448 
5449                 cldec.members.push(ctor);
5450                 ctor.addMember(sc, cldec);
5451                 ctor.dsymbolSemantic(sc2);
5452 
5453                 cldec.ctor = ctor;
5454                 cldec.defaultCtor = ctor;
5455             }
5456             else
5457             {
5458                 cldec.error("cannot implicitly generate a default constructor when base class `%s` is missing a default constructor",
5459                     cldec.baseClass.toPrettyChars());
5460             }
5461         }
5462 
5463         cldec.dtor = buildDtor(cldec, sc2);
5464         cldec.tidtor = buildExternDDtor(cldec, sc2);
5465 
5466         if (cldec.classKind == ClassKind.cpp && cldec.cppDtorVtblIndex != -1)
5467         {
5468             // now we've built the aggregate destructor, we'll make it virtual and assign it to the reserved vtable slot
5469             cldec.dtor.vtblIndex = cldec.cppDtorVtblIndex;
5470             cldec.vtbl[cldec.cppDtorVtblIndex] = cldec.dtor;
5471 
5472             if (target.cpp.twoDtorInVtable)
5473             {
5474                 // TODO: create a C++ compatible deleting destructor (call out to `operator delete`)
5475                 //       for the moment, we'll call the non-deleting destructor and leak
5476                 cldec.vtbl[cldec.cppDtorVtblIndex + 1] = cldec.dtor;
5477             }
5478         }
5479 
5480         if (auto f = hasIdentityOpAssign(cldec, sc2))
5481         {
5482             if (!(f.storage_class & STC.disable))
5483                 cldec.error(f.loc, "identity assignment operator overload is illegal");
5484         }
5485 
5486         cldec.inv = buildInv(cldec, sc2);
5487         if (cldec.inv)
5488             reinforceInvariant(cldec, sc2);
5489 
5490         Module.dprogress++;
5491         cldec.semanticRun = PASS.semanticdone;
5492         //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5493 
5494         sc2.pop();
5495 
5496         /* isAbstract() is undecidable in some cases because of circular dependencies.
5497          * Now that semantic is finished, get a definitive result, and error if it is not the same.
5498          */
5499         if (cldec.isabstract != Abstract.fwdref)    // if evaluated it before completion
5500         {
5501             const isabstractsave = cldec.isabstract;
5502             cldec.isabstract = Abstract.fwdref;
5503             cldec.isAbstract();               // recalculate
5504             if (cldec.isabstract != isabstractsave)
5505             {
5506                 cldec.error("cannot infer `abstract` attribute due to circular dependencies");
5507             }
5508         }
5509 
5510         if (cldec.type.ty == Tclass && (cast(TypeClass)cldec.type).sym != cldec)
5511         {
5512             // https://issues.dlang.org/show_bug.cgi?id=17492
5513             ClassDeclaration cd = (cast(TypeClass)cldec.type).sym;
5514             version (none)
5515             {
5516                 printf("this = %p %s\n", cldec, cldec.toPrettyChars());
5517                 printf("type = %d sym = %p, %s\n", cldec.type.ty, cd, cd.toPrettyChars());
5518             }
5519             cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars());
5520         }
5521 
5522         if (global.errors != errors)
5523         {
5524             // The type is no good.
5525             cldec.type = Type.terror;
5526             cldec.errors = true;
5527             if (cldec.deferred)
5528                 cldec.deferred.errors = true;
5529         }
5530 
5531         // Verify fields of a synchronized class are not public
5532         if (cldec.storage_class & STC.synchronized_)
5533         {
5534             foreach (vd; cldec.fields)
5535             {
5536                 if (!vd.isThisDeclaration() &&
5537                     !vd.prot().isMoreRestrictiveThan(Prot(Prot.Kind.public_)))
5538                 {
5539                     vd.error("Field members of a `synchronized` class cannot be `%s`",
5540                         protectionToChars(vd.prot().kind));
5541                 }
5542             }
5543         }
5544 
5545         if (cldec.deferred && !global.gag)
5546         {
5547             cldec.deferred.semantic2(sc);
5548             cldec.deferred.semantic3(sc);
5549         }
5550         //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
5551 
5552         // @@@DEPRECATED@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5553         // Deprecated in 2.087
5554         // Make an error in 2.091
5555         // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5556         if (0 &&          // deprecation disabled for now to accommodate existing extensive use
5557             cldec.storage_class & STC.scope_)
5558             deprecation(cldec.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
5559 
5560         checkInterfaceImplementations(cldec);
5561     }
5562 
5563     override void visit(InterfaceDeclaration idec)
5564     {
5565         /// Returns: `true` is this is an anonymous Objective-C metaclass
5566         static bool isAnonymousMetaclass(InterfaceDeclaration idec)
5567         {
5568             return idec.classKind == ClassKind.objc &&
5569                 idec.objc.isMeta &&
5570                 idec.isAnonymous;
5571         }
5572 
5573         //printf("InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5574         if (idec.semanticRun >= PASS.semanticdone)
5575             return;
5576         int errors = global.errors;
5577 
5578         //printf("+InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5579 
5580         Scope* scx = null;
5581         if (idec._scope)
5582         {
5583             sc = idec._scope;
5584             scx = idec._scope; // save so we don't make redundant copies
5585             idec._scope = null;
5586         }
5587 
5588         if (!idec.parent)
5589         {
5590             assert(sc.parent && sc.func);
5591             idec.parent = sc.parent;
5592         }
5593         // Objective-C metaclasses are anonymous
5594         assert(idec.parent && !idec.isAnonymous || isAnonymousMetaclass(idec));
5595 
5596         if (idec.errors)
5597             idec.type = Type.terror;
5598         idec.type = idec.type.typeSemantic(idec.loc, sc);
5599         if (idec.type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5600         {
5601             auto ti = (cast(TypeClass)idec.type).sym.isInstantiated();
5602             if (ti && isError(ti))
5603                 (cast(TypeClass)idec.type).sym = idec;
5604         }
5605 
5606         // Ungag errors when not speculative
5607         Ungag ungag = idec.ungagSpeculative();
5608 
5609         if (idec.semanticRun == PASS.init)
5610         {
5611             idec.protection = sc.protection;
5612 
5613             idec.storage_class |= sc.stc;
5614             idec.userAttribDecl = sc.userAttribDecl;
5615         }
5616         else if (idec.symtab)
5617         {
5618             if (idec.sizeok == Sizeok.done || !scx)
5619             {
5620                 idec.semanticRun = PASS.semanticdone;
5621                 return;
5622             }
5623         }
5624         idec.semanticRun = PASS.semantic;
5625 
5626         if (idec.baseok < Baseok.done)
5627         {
5628             T resolveBase(T)(lazy T exp)
5629             {
5630                 if (!scx)
5631                 {
5632                     scx = sc.copy();
5633                     scx.setNoFree();
5634                 }
5635                 static if (!is(T == void))
5636                 {
5637                     idec._scope = scx;
5638                     auto r = exp();
5639                     idec._scope = null;
5640                     return r;
5641                 }
5642                 else
5643                 {
5644                     idec._scope = scx;
5645                     exp();
5646                     idec._scope = null;
5647                 }
5648             }
5649 
5650             idec.baseok = Baseok.start;
5651 
5652             // Expand any tuples in baseclasses[]
5653             for (size_t i = 0; i < idec.baseclasses.dim;)
5654             {
5655                 auto b = (*idec.baseclasses)[i];
5656                 b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));
5657 
5658                 Type tb = b.type.toBasetype();
5659                 if (auto tup = tb.isTypeTuple())
5660                 {
5661                     idec.baseclasses.remove(i);
5662                     size_t dim = Parameter.dim(tup.arguments);
5663                     for (size_t j = 0; j < dim; j++)
5664                     {
5665                         Parameter arg = Parameter.getNth(tup.arguments, j);
5666                         b = new BaseClass(arg.type);
5667                         idec.baseclasses.insert(i + j, b);
5668                     }
5669                 }
5670                 else
5671                     i++;
5672             }
5673 
5674             if (idec.baseok >= Baseok.done)
5675             {
5676                 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
5677                 if (idec.semanticRun >= PASS.semanticdone)
5678                     return;
5679                 goto Lancestorsdone;
5680             }
5681 
5682             if (!idec.baseclasses.dim && sc.linkage == LINK.cpp)
5683                 idec.classKind = ClassKind.cpp;
5684             idec.cppnamespace = sc.namespace;
5685             UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
5686 
5687             if (sc.linkage == LINK.objc)
5688             {
5689                 objc.setObjc(idec);
5690                 objc.deprecate(idec);
5691             }
5692 
5693             // Check for errors, handle forward references
5694             BCLoop:
5695             for (size_t i = 0; i < idec.baseclasses.dim;)
5696             {
5697                 BaseClass* b = (*idec.baseclasses)[i];
5698                 Type tb = b.type.toBasetype();
5699                 TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;
5700                 if (!tc || !tc.sym.isInterfaceDeclaration())
5701                 {
5702                     if (b.type != Type.terror)
5703                         idec.error("base type must be `interface`, not `%s`", b.type.toChars());
5704                     idec.baseclasses.remove(i);
5705                     continue;
5706                 }
5707 
5708                 // Check for duplicate interfaces
5709                 for (size_t j = 0; j < i; j++)
5710                 {
5711                     BaseClass* b2 = (*idec.baseclasses)[j];
5712                     if (b2.sym == tc.sym)
5713                     {
5714                         idec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
5715                         idec.baseclasses.remove(i);
5716                         continue BCLoop;
5717                     }
5718                 }
5719                 if (tc.sym == idec || idec.isBaseOf2(tc.sym))
5720                 {
5721                     idec.error("circular inheritance of interface");
5722                     idec.baseclasses.remove(i);
5723                     continue;
5724                 }
5725                 if (tc.sym.isDeprecated())
5726                 {
5727                     if (!idec.isDeprecated())
5728                     {
5729                         // Deriving from deprecated interface makes this one deprecated too
5730                         idec.setDeprecated();
5731                         tc.checkDeprecated(idec.loc, sc);
5732                     }
5733                 }
5734 
5735                 b.sym = tc.sym;
5736 
5737                 if (tc.sym.baseok < Baseok.done)
5738                     resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5739                 if (tc.sym.baseok < Baseok.done)
5740                 {
5741                     //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
5742                     if (tc.sym._scope)
5743                         Module.addDeferredSemantic(tc.sym);
5744                     idec.baseok = Baseok.none;
5745                 }
5746                 i++;
5747             }
5748             if (idec.baseok == Baseok.none)
5749             {
5750                 // Forward referencee of one or more bases, try again later
5751                 return deferDsymbolSemantic(idec, scx);
5752             }
5753             idec.baseok = Baseok.done;
5754 
5755             idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.dim];
5756             foreach (b; idec.interfaces)
5757             {
5758                 // If this is an interface, and it derives from a COM interface,
5759                 // then this is a COM interface too.
5760                 if (b.sym.isCOMinterface())
5761                     idec.com = true;
5762                 if (b.sym.isCPPinterface())
5763                     idec.classKind = ClassKind.cpp;
5764             }
5765 
5766             interfaceSemantic(idec);
5767         }
5768     Lancestorsdone:
5769 
5770         if (!idec.members) // if opaque declaration
5771         {
5772             idec.semanticRun = PASS.semanticdone;
5773             return;
5774         }
5775         if (!idec.symtab)
5776             idec.symtab = new DsymbolTable();
5777 
5778         for (size_t i = 0; i < idec.baseclasses.dim; i++)
5779         {
5780             BaseClass* b = (*idec.baseclasses)[i];
5781             Type tb = b.type.toBasetype();
5782             TypeClass tc = tb.isTypeClass();
5783             if (tc.sym.semanticRun < PASS.semanticdone)
5784             {
5785                 // Forward referencee of one or more bases, try again later
5786                 if (tc.sym._scope)
5787                     Module.addDeferredSemantic(tc.sym);
5788                 return deferDsymbolSemantic(idec, scx);
5789             }
5790         }
5791 
5792         if (idec.baseok == Baseok.done)
5793         {
5794             idec.baseok = Baseok.semanticdone;
5795             objc.setMetaclass(idec, sc);
5796 
5797             // initialize vtbl
5798             if (idec.vtblOffset())
5799                 idec.vtbl.push(idec); // leave room at vtbl[0] for classinfo
5800 
5801             // Cat together the vtbl[]'s from base interfaces
5802             foreach (i, b; idec.interfaces)
5803             {
5804                 // Skip if b has already appeared
5805                 for (size_t k = 0; k < i; k++)
5806                 {
5807                     if (b == idec.interfaces[k])
5808                         goto Lcontinue;
5809                 }
5810 
5811                 // Copy vtbl[] from base class
5812                 if (b.sym.vtblOffset())
5813                 {
5814                     size_t d = b.sym.vtbl.dim;
5815                     if (d > 1)
5816                     {
5817                         idec.vtbl.pushSlice(b.sym.vtbl[1 .. d]);
5818                     }
5819                 }
5820                 else
5821                 {
5822                     idec.vtbl.append(&b.sym.vtbl);
5823                 }
5824 
5825             Lcontinue:
5826             }
5827         }
5828 
5829         idec.members.foreachDsymbol( s => s.addMember(sc, idec) );
5830 
5831         auto sc2 = idec.newScope(sc);
5832 
5833         /* Set scope so if there are forward references, we still might be able to
5834          * resolve individual members like enums.
5835          */
5836         idec.members.foreachDsymbol( s => s.setScope(sc2) );
5837 
5838         idec.members.foreachDsymbol( s => s.importAll(sc2) );
5839 
5840         idec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
5841 
5842         Module.dprogress++;
5843         idec.semanticRun = PASS.semanticdone;
5844         //printf("-InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5845 
5846         sc2.pop();
5847 
5848         if (global.errors != errors)
5849         {
5850             // The type is no good.
5851             idec.type = Type.terror;
5852         }
5853 
5854         version (none)
5855         {
5856             if (type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5857             {
5858                 printf("this = %p %s\n", idec, idec.toChars());
5859                 printf("type = %d sym = %p\n", idec.type.ty, (cast(TypeClass)idec.type).sym);
5860             }
5861         }
5862         assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec);
5863 
5864         // @@@DEPRECATED@@@https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5865         // Deprecated in 2.087
5866         // Remove in 2.091
5867         // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5868         if (idec.storage_class & STC.scope_)
5869             deprecation(idec.loc, "`scope` as a type constraint is deprecated.  Use `scope` at the usage site.");
5870     }
5871 }
5872 
5873 void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* fargs)
5874 {
5875     //printf("[%s] TemplateInstance.dsymbolSemantic('%s', this=%p, gag = %d, sc = %p)\n", tempinst.loc.toChars(), tempinst.toChars(), tempinst, global.gag, sc);
5876     version (none)
5877     {
5878         for (Dsymbol s = tempinst; s; s = s.parent)
5879         {
5880             printf("\t%s\n", s.toChars());
5881         }
5882         printf("Scope\n");
5883         for (Scope* scx = sc; scx; scx = scx.enclosing)
5884         {
5885             printf("\t%s parent %s\n", scx._module ? scx._module.toChars() : "null", scx.parent ? scx.parent.toChars() : "null");
5886         }
5887     }
5888 
5889     static if (LOG)
5890     {
5891         printf("\n+TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
5892     }
5893     if (tempinst.inst) // if semantic() was already run
5894     {
5895         static if (LOG)
5896         {
5897             printf("-TemplateInstance.dsymbolSemantic('%s', this=%p) already run\n",
5898                    tempinst.inst.toChars(), tempinst.inst);
5899         }
5900         return;
5901     }
5902     if (tempinst.semanticRun != PASS.init)
5903     {
5904         static if (LOG)
5905         {
5906             printf("Recursive template expansion\n");
5907         }
5908         auto ungag = Ungag(global.gag);
5909         if (!tempinst.gagged)
5910             global.gag = 0;
5911         tempinst.error(tempinst.loc, "recursive template expansion");
5912         if (tempinst.gagged)
5913             tempinst.semanticRun = PASS.init;
5914         else
5915             tempinst.inst = tempinst;
5916         tempinst.errors = true;
5917         return;
5918     }
5919 
5920     // Get the enclosing template instance from the scope tinst
5921     tempinst.tinst = sc.tinst;
5922 
5923     // Get the instantiating module from the scope minst
5924     tempinst.minst = sc.minst;
5925     // https://issues.dlang.org/show_bug.cgi?id=10920
5926     // If the enclosing function is non-root symbol,
5927     // this instance should be speculative.
5928     if (!tempinst.tinst && sc.func && sc.func.inNonRoot())
5929     {
5930         tempinst.minst = null;
5931     }
5932     // https://issues.dlang.org/show_bug.cgi?id=21299
5933     // If not speculative, this instance should have the same instantiating
5934     // root module as its enclosing template symbol. This can differ when
5935     // the enclosing template gets changed from non-root to a root instance
5936     // in the instantiation graph. When that occurs, this instance also
5937     // needs to be appended to the root module, otherwise there will be
5938     // undefined references at link-time.
5939     if (tempinst.minst && tempinst.tinst)
5940     {
5941         tempinst.minst = tempinst.tinst.minst;
5942     }
5943 
5944     tempinst.gagged = (global.gag > 0);
5945 
5946     tempinst.semanticRun = PASS.semantic;
5947 
5948     static if (LOG)
5949     {
5950         printf("\tdo semantic\n");
5951     }
5952     /* Find template declaration first,
5953      * then run semantic on each argument (place results in tiargs[]),
5954      * last find most specialized template from overload list/set.
5955      */
5956     if (!tempinst.findTempDecl(sc, null) || !tempinst.semanticTiargs(sc) || !tempinst.findBestMatch(sc, fargs))
5957     {
5958     Lerror:
5959         if (tempinst.gagged)
5960         {
5961             // https://issues.dlang.org/show_bug.cgi?id=13220
5962             // Roll back status for later semantic re-running
5963             tempinst.semanticRun = PASS.init;
5964         }
5965         else
5966             tempinst.inst = tempinst;
5967         tempinst.errors = true;
5968         return;
5969     }
5970     TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();
5971     assert(tempdecl);
5972 
5973     TemplateStats.incInstance(tempdecl, tempinst);
5974 
5975     tempdecl.checkDeprecated(tempinst.loc, sc);
5976 
5977     // If tempdecl is a mixin, disallow it
5978     if (tempdecl.ismixin)
5979     {
5980         tempinst.error("mixin templates are not regular templates");
5981         goto Lerror;
5982     }
5983 
5984     tempinst.hasNestedArgs(tempinst.tiargs, tempdecl.isstatic);
5985     if (tempinst.errors)
5986         goto Lerror;
5987 
5988     // Copy the tempdecl namespace (not the scope one)
5989     tempinst.cppnamespace = tempdecl.cppnamespace;
5990     if (tempinst.cppnamespace)
5991         tempinst.cppnamespace.dsymbolSemantic(sc);
5992 
5993     /* Greatly simplified semantic processing for AliasSeq templates
5994      */
5995     if (tempdecl.isTrivialAliasSeq)
5996     {
5997         tempinst.inst = tempinst;
5998         return aliasSeqInstanceSemantic(tempinst, sc, fargs, tempdecl);
5999     }
6000 
6001     /* Greatly simplified semantic processing for Alias templates
6002      */
6003     else if (tempdecl.isTrivialAlias)
6004     {
6005         tempinst.inst = tempinst;
6006         return aliasInstanceSemantic(tempinst, sc, fargs, tempdecl);
6007     }
6008 
6009     /* See if there is an existing TemplateInstantiation that already
6010      * implements the typeargs. If so, just refer to that one instead.
6011      */
6012     tempinst.inst = tempdecl.findExistingInstance(tempinst, fargs);
6013     TemplateInstance errinst = null;
6014     if (!tempinst.inst)
6015     {
6016         // So, we need to implement 'this' instance.
6017     }
6018     else if (tempinst.inst.gagged && !tempinst.gagged && tempinst.inst.errors)
6019     {
6020         // If the first instantiation had failed, re-run semantic,
6021         // so that error messages are shown.
6022         errinst = tempinst.inst;
6023     }
6024     else
6025     {
6026         // It's a match
6027         tempinst.parent = tempinst.inst.parent;
6028         tempinst.errors = tempinst.inst.errors;
6029 
6030         // If both this and the previous instantiation were gagged,
6031         // use the number of errors that happened last time.
6032         global.errors += tempinst.errors;
6033         global.gaggedErrors += tempinst.errors;
6034 
6035         // If the first instantiation was gagged, but this is not:
6036         if (tempinst.inst.gagged)
6037         {
6038             // It had succeeded, mark it is a non-gagged instantiation,
6039             // and reuse it.
6040             tempinst.inst.gagged = tempinst.gagged;
6041         }
6042 
6043         tempinst.tnext = tempinst.inst.tnext;
6044         tempinst.inst.tnext = tempinst;
6045 
6046         /* A module can have explicit template instance and its alias
6047          * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).
6048          * If the first instantiation 'inst' had happened in non-root module,
6049          * compiler can assume that its instantiated code would be included
6050          * in the separately compiled obj/lib file (e.g. phobos.lib).
6051          *
6052          * However, if 'this' second instantiation happened in root module,
6053          * compiler might need to invoke its codegen
6054          * (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang.org/show_bug.cgi?id=2644).
6055          * But whole import graph is not determined until all semantic pass finished,
6056          * so 'inst' should conservatively finish the semantic3 pass for the codegen.
6057          */
6058         if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst && tempinst.inst.minst.isRoot()))
6059         {
6060             /* Swap the position of 'inst' and 'this' in the instantiation graph.
6061              * Then, the primary instance `inst` will be changed to a root instance.
6062              *
6063              * Before:
6064              *  non-root -> A!() -> B!()[inst] -> C!()
6065              *                      |
6066              *  root     -> D!() -> B!()[this]
6067              *
6068              * After:
6069              *  non-root -> A!() -> B!()[this]
6070              *                      |
6071              *  root     -> D!() -> B!()[inst] -> C!()
6072              */
6073             Module mi = tempinst.minst;
6074             TemplateInstance ti = tempinst.tinst;
6075             tempinst.minst = tempinst.inst.minst;
6076             tempinst.tinst = tempinst.inst.tinst;
6077             tempinst.inst.minst = mi;
6078             tempinst.inst.tinst = ti;
6079 
6080             if (tempinst.minst) // if inst was not speculative
6081             {
6082                 /* Add 'inst' once again to the root module members[], then the
6083                  * instance members will get codegen chances.
6084                  */
6085                 tempinst.inst.appendToModuleMember();
6086             }
6087         }
6088 
6089         // modules imported by an existing instance should be added to the module
6090         // that instantiates the instance.
6091         if (tempinst.minst)
6092             foreach(imp; tempinst.inst.importedModules)
6093                 if (!tempinst.minst.aimports.contains(imp))
6094                     tempinst.minst.aimports.push(imp);
6095 
6096         static if (LOG)
6097         {
6098             printf("\tit's a match with instance %p, %d\n", tempinst.inst, tempinst.inst.semanticRun);
6099         }
6100         return;
6101     }
6102     static if (LOG)
6103     {
6104         printf("\timplement template instance %s '%s'\n", tempdecl.parent.toChars(), tempinst.toChars());
6105         printf("\ttempdecl %s\n", tempdecl.toChars());
6106     }
6107     uint errorsave = global.errors;
6108 
6109     tempinst.inst = tempinst;
6110     tempinst.parent = tempinst.enclosing ? tempinst.enclosing : tempdecl.parent;
6111     //printf("parent = '%s'\n", parent.kind());
6112 
6113     TemplateStats.incUnique(tempdecl, tempinst);
6114 
6115     TemplateInstance tempdecl_instance_idx = tempdecl.addInstance(tempinst);
6116 
6117     //getIdent();
6118 
6119     // Store the place we added it to in target_symbol_list(_idx) so we can
6120     // remove it later if we encounter an error.
6121     Dsymbols* target_symbol_list = tempinst.appendToModuleMember();
6122     size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.dim - 1 : 0;
6123 
6124     // Copy the syntax trees from the TemplateDeclaration
6125     tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
6126 
6127     // resolve TemplateThisParameter
6128     for (size_t i = 0; i < tempdecl.parameters.dim; i++)
6129     {
6130         if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)
6131             continue;
6132         Type t = isType((*tempinst.tiargs)[i]);
6133         assert(t);
6134         if (StorageClass stc = ModToStc(t.mod))
6135         {
6136             //printf("t = %s, stc = x%llx\n", t.toChars(), stc);
6137             auto s = new Dsymbols();
6138             s.push(new StorageClassDeclaration(stc, tempinst.members));
6139             tempinst.members = s;
6140         }
6141         break;
6142     }
6143 
6144     // Create our own scope for the template parameters
6145     Scope* _scope = tempdecl._scope;
6146     if (tempdecl.semanticRun == PASS.init)
6147     {
6148         tempinst.error("template instantiation `%s` forward references template declaration `%s`", tempinst.toChars(), tempdecl.toChars());
6149         return;
6150     }
6151 
6152     static if (LOG)
6153     {
6154         printf("\tcreate scope for template parameters '%s'\n", tempinst.toChars());
6155     }
6156     tempinst.argsym = new ScopeDsymbol();
6157     tempinst.argsym.parent = _scope.parent;
6158     _scope = _scope.push(tempinst.argsym);
6159     _scope.tinst = tempinst;
6160     _scope.minst = tempinst.minst;
6161     //scope.stc = 0;
6162 
6163     // Declare each template parameter as an alias for the argument type
6164     Scope* paramscope = _scope.push();
6165     paramscope.stc = 0;
6166     paramscope.protection = Prot(Prot.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=14169
6167                                               // template parameters should be public
6168     tempinst.declareParameters(paramscope);
6169     paramscope.pop();
6170 
6171     // Add members of template instance to template instance symbol table
6172     //parent = scope.scopesym;
6173     tempinst.symtab = new DsymbolTable();
6174 
6175     tempinst.members.foreachDsymbol( (s)
6176     {
6177         static if (LOG)
6178         {
6179             printf("\t adding member '%s' %p kind %s to '%s'\n", s.toChars(), s, s.kind(), tempinst.toChars());
6180         }
6181         s.addMember(_scope, tempinst);
6182     });
6183 
6184     static if (LOG)
6185     {
6186         printf("adding members done\n");
6187     }
6188 
6189     /* See if there is only one member of template instance, and that
6190      * member has the same name as the template instance.
6191      * If so, this template instance becomes an alias for that member.
6192      */
6193     //printf("members.dim = %d\n", tempinst.members.dim);
6194     if (tempinst.members.dim)
6195     {
6196         Dsymbol s;
6197         if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
6198         {
6199             //printf("tempdecl.ident = %s, s = '%s'\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
6200             //printf("setting aliasdecl\n");
6201             tempinst.aliasdecl = s;
6202         }
6203     }
6204 
6205     /* If function template declaration
6206      */
6207     if (fargs && tempinst.aliasdecl)
6208     {
6209         if (auto fd = tempinst.aliasdecl.isFuncDeclaration())
6210         {
6211             /* Transmit fargs to type so that TypeFunction.dsymbolSemantic() can
6212              * resolve any "auto ref" storage classes.
6213              */
6214             if (fd.type)
6215                 if (auto tf = fd.type.isTypeFunction())
6216                     tf.fargs = fargs;
6217         }
6218     }
6219 
6220     // Do semantic() analysis on template instance members
6221     static if (LOG)
6222     {
6223         printf("\tdo semantic() on template instance members '%s'\n", tempinst.toChars());
6224     }
6225     Scope* sc2;
6226     sc2 = _scope.push(tempinst);
6227     //printf("enclosing = %d, sc.parent = %s\n", tempinst.enclosing, sc.parent.toChars());
6228     sc2.parent = tempinst;
6229     sc2.tinst = tempinst;
6230     sc2.minst = tempinst.minst;
6231     sc2.stc &= ~STC.deprecated_;
6232     tempinst.tryExpandMembers(sc2);
6233 
6234     tempinst.semanticRun = PASS.semanticdone;
6235 
6236     /* ConditionalDeclaration may introduce eponymous declaration,
6237      * so we should find it once again after semantic.
6238      */
6239     if (tempinst.members.dim)
6240     {
6241         Dsymbol s;
6242         if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
6243         {
6244             if (!tempinst.aliasdecl || tempinst.aliasdecl != s)
6245             {
6246                 //printf("tempdecl.ident = %s, s = '%s'\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
6247                 //printf("setting aliasdecl 2\n");
6248                 tempinst.aliasdecl = s;
6249             }
6250         }
6251     }
6252 
6253     if (global.errors != errorsave)
6254         goto Laftersemantic;
6255 
6256     /* If any of the instantiation members didn't get semantic() run
6257      * on them due to forward references, we cannot run semantic2()
6258      * or semantic3() yet.
6259      */
6260     {
6261         bool found_deferred_ad = false;
6262         for (size_t i = 0; i < Module.deferred.dim; i++)
6263         {
6264             Dsymbol sd = Module.deferred[i];
6265             AggregateDeclaration ad = sd.isAggregateDeclaration();
6266             if (ad && ad.parent && ad.parent.isTemplateInstance())
6267             {
6268                 //printf("deferred template aggregate: %s %s\n",
6269                 //        sd.parent.toChars(), sd.toChars());
6270                 found_deferred_ad = true;
6271                 if (ad.parent == tempinst)
6272                 {
6273                     ad.deferred = tempinst;
6274                     break;
6275                 }
6276             }
6277         }
6278         if (found_deferred_ad || Module.deferred.dim)
6279             goto Laftersemantic;
6280     }
6281 
6282     /* The problem is when to parse the initializer for a variable.
6283      * Perhaps VarDeclaration.dsymbolSemantic() should do it like it does
6284      * for initializers inside a function.
6285      */
6286     //if (sc.parent.isFuncDeclaration())
6287     {
6288         /* https://issues.dlang.org/show_bug.cgi?id=782
6289          * this has problems if the classes this depends on
6290          * are forward referenced. Find a way to defer semantic()
6291          * on this template.
6292          */
6293         tempinst.semantic2(sc2);
6294     }
6295     if (global.errors != errorsave)
6296         goto Laftersemantic;
6297 
6298     if ((sc.func || (sc.flags & SCOPE.fullinst)) && !tempinst.tinst)
6299     {
6300         /* If a template is instantiated inside function, the whole instantiation
6301          * should be done at that position. But, immediate running semantic3 of
6302          * dependent templates may cause unresolved forward reference.
6303          * https://issues.dlang.org/show_bug.cgi?id=9050
6304          * To avoid the issue, don't run semantic3 until semantic and semantic2 done.
6305          */
6306         TemplateInstances deferred;
6307         tempinst.deferred = &deferred;
6308 
6309         //printf("Run semantic3 on %s\n", toChars());
6310         tempinst.trySemantic3(sc2);
6311 
6312         for (size_t i = 0; i < deferred.dim; i++)
6313         {
6314             //printf("+ run deferred semantic3 on %s\n", deferred[i].toChars());
6315             deferred[i].semantic3(null);
6316         }
6317 
6318         tempinst.deferred = null;
6319     }
6320     else if (tempinst.tinst)
6321     {
6322         bool doSemantic3 = false;
6323         FuncDeclaration fd;
6324         if (tempinst.aliasdecl)
6325             fd = tempinst.aliasdecl.toAlias2().isFuncDeclaration();
6326 
6327         if (fd)
6328         {
6329             /* Template function instantiation should run semantic3 immediately
6330              * for attribute inference.
6331              */
6332             scope fld = fd.isFuncLiteralDeclaration();
6333             if (fld && fld.tok == TOK.reserved)
6334                 doSemantic3 = true;
6335             else if (sc.func)
6336                 doSemantic3 = true;
6337         }
6338         else if (sc.func)
6339         {
6340             /* A lambda function in template arguments might capture the
6341              * instantiated scope context. For the correct context inference,
6342              * all instantiated functions should run the semantic3 immediately.
6343              * See also compilable/test14973.d
6344              */
6345             foreach (oarg; tempinst.tdtypes)
6346             {
6347                 auto s = getDsymbol(oarg);
6348                 if (!s)
6349                     continue;
6350 
6351                 if (auto td = s.isTemplateDeclaration())
6352                 {
6353                     if (!td.literal)
6354                         continue;
6355                     assert(td.members && td.members.dim == 1);
6356                     s = (*td.members)[0];
6357                 }
6358                 if (auto fld = s.isFuncLiteralDeclaration())
6359                 {
6360                     if (fld.tok == TOK.reserved)
6361                     {
6362                         doSemantic3 = true;
6363                         break;
6364                     }
6365                 }
6366             }
6367             //printf("[%s] %s doSemantic3 = %d\n", tempinst.tinst.loc.toChars(), tempinst.tinst.toChars(), doSemantic3);
6368         }
6369         if (doSemantic3)
6370             tempinst.trySemantic3(sc2);
6371 
6372         TemplateInstance ti = tempinst.tinst;
6373         int nest = 0;
6374         while (ti && !ti.deferred && ti.tinst)
6375         {
6376             ti = ti.tinst;
6377             if (++nest > global.recursionLimit)
6378             {
6379                 global.gag = 0; // ensure error message gets printed
6380                 tempinst.error("recursive expansion");
6381                 fatal();
6382             }
6383         }
6384         if (ti && ti.deferred)
6385         {
6386             //printf("deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\n", this, toChars(), ti.toChars());
6387             for (size_t i = 0;; i++)
6388             {
6389                 if (i == ti.deferred.dim)
6390                 {
6391                     ti.deferred.push(tempinst);
6392                     break;
6393                 }
6394                 if ((*ti.deferred)[i] == tempinst)
6395                     break;
6396             }
6397         }
6398     }
6399 
6400     if (tempinst.aliasdecl)
6401     {
6402         /* https://issues.dlang.org/show_bug.cgi?id=13816
6403          * AliasDeclaration tries to resolve forward reference
6404          * twice (See inuse check in AliasDeclaration.toAlias()). It's
6405          * necessary to resolve mutual references of instantiated symbols, but
6406          * it will left a true recursive alias in tuple declaration - an
6407          * AliasDeclaration A refers TupleDeclaration B, and B contains A
6408          * in its elements.  To correctly make it an error, we strictly need to
6409          * resolve the alias of eponymous member.
6410          */
6411         tempinst.aliasdecl = tempinst.aliasdecl.toAlias2();
6412     }
6413 
6414 Laftersemantic:
6415     sc2.pop();
6416     _scope.pop();
6417 
6418     // Give additional context info if error occurred during instantiation
6419     if (global.errors != errorsave)
6420     {
6421         if (!tempinst.errors)
6422         {
6423             if (!tempdecl.literal)
6424                 tempinst.error(tempinst.loc, "error instantiating");
6425             if (tempinst.tinst)
6426                 tempinst.tinst.printInstantiationTrace();
6427         }
6428         tempinst.errors = true;
6429         if (tempinst.gagged)
6430         {
6431             // Errors are gagged, so remove the template instance from the
6432             // instance/symbol lists we added it to and reset our state to
6433             // finish clean and so we can try to instantiate it again later
6434             // (see https://issues.dlang.org/show_bug.cgi?id=4302 and https://issues.dlang.org/show_bug.cgi?id=6602).
6435             tempdecl.removeInstance(tempdecl_instance_idx);
6436             if (target_symbol_list)
6437             {
6438                 // Because we added 'this' in the last position above, we
6439                 // should be able to remove it without messing other indices up.
6440                 assert((*target_symbol_list)[target_symbol_list_idx] == tempinst);
6441                 target_symbol_list.remove(target_symbol_list_idx);
6442                 tempinst.memberOf = null;                    // no longer a member
6443             }
6444             tempinst.semanticRun = PASS.init;
6445             tempinst.inst = null;
6446             tempinst.symtab = null;
6447         }
6448     }
6449     else if (errinst)
6450     {
6451         /* https://issues.dlang.org/show_bug.cgi?id=14541
6452          * If the previous gagged instance had failed by
6453          * circular references, currrent "error reproduction instantiation"
6454          * might succeed, because of the difference of instantiated context.
6455          * On such case, the cached error instance needs to be overridden by the
6456          * succeeded instance.
6457          */
6458         //printf("replaceInstance()\n");
6459         assert(errinst.errors);
6460         auto ti1 = TemplateInstanceBox(errinst);
6461         tempdecl.instances.remove(ti1);
6462 
6463         auto ti2 = TemplateInstanceBox(tempinst);
6464         tempdecl.instances[ti2] = tempinst;
6465     }
6466 
6467     static if (LOG)
6468     {
6469         printf("-TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
6470     }
6471 }
6472 
6473 /******************************************************
6474  * Do template instance semantic for isAliasSeq templates.
6475  * This is a greatly simplified version of templateInstanceSemantic().
6476  */
6477 private
6478 void aliasSeqInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* fargs, TemplateDeclaration tempdecl)
6479 {
6480     //printf("[%s] aliasSeqInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6481     Scope* paramscope = sc.push();
6482     paramscope.stc = 0;
6483     paramscope.protection = Prot(Prot.Kind.public_);
6484 
6485     TemplateTupleParameter ttp = (*tempdecl.parameters)[0].isTemplateTupleParameter();
6486     Tuple va = tempinst.tdtypes[0].isTuple();
6487     Declaration d = new TupleDeclaration(tempinst.loc, ttp.ident, &va.objects);
6488     d.storage_class |= STC.templateparameter;
6489     d.dsymbolSemantic(sc);
6490 
6491     paramscope.pop();
6492 
6493     tempinst.aliasdecl = d;
6494 
6495     tempinst.semanticRun = PASS.semanticdone;
6496 }
6497 
6498 /******************************************************
6499  * Do template instance semantic for isAlias templates.
6500  * This is a greatly simplified version of templateInstanceSemantic().
6501  */
6502 private
6503 void aliasInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* fargs, TemplateDeclaration tempdecl)
6504 {
6505     //printf("[%s] aliasInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6506     Scope* paramscope = sc.push();
6507     paramscope.stc = 0;
6508     paramscope.protection = Prot(Prot.Kind.public_);
6509 
6510     TemplateTypeParameter ttp = (*tempdecl.parameters)[0].isTemplateTypeParameter();
6511     Type ta = tempinst.tdtypes[0].isType();
6512     Declaration d = new AliasDeclaration(tempinst.loc, ttp.ident, ta.addMod(tempdecl.onemember.isAliasDeclaration.type.mod));
6513     d.storage_class |= STC.templateparameter;
6514     d.dsymbolSemantic(sc);
6515 
6516     paramscope.pop();
6517 
6518     tempinst.aliasdecl = d;
6519 
6520     tempinst.semanticRun = PASS.semanticdone;
6521 }
6522 
6523 // function used to perform semantic on AliasDeclaration
6524 void aliasSemantic(AliasDeclaration ds, Scope* sc)
6525 {
6526     //printf("AliasDeclaration::semantic() %s\n", ds.toChars());
6527 
6528     // as DsymbolSemanticVisitor::visit(AliasDeclaration), in case we're called first.
6529     // see https://issues.dlang.org/show_bug.cgi?id=21001
6530     ds.storage_class |= sc.stc & STC.deprecated_;
6531     ds.protection = sc.protection;
6532     ds.userAttribDecl = sc.userAttribDecl;
6533 
6534     // TypeTraits needs to know if it's located in an AliasDeclaration
6535     const oldflags = sc.flags;
6536     sc.flags |= SCOPE.alias_;
6537     scope(exit)
6538         sc.flags = oldflags;
6539 
6540     // preserve the original type
6541     if (!ds.originalType && ds.type)
6542         ds.originalType = ds.type.syntaxCopy();
6543 
6544     if (ds.aliassym)
6545     {
6546         auto fd = ds.aliassym.isFuncLiteralDeclaration();
6547         auto td = ds.aliassym.isTemplateDeclaration();
6548         if (fd || td && td.literal)
6549         {
6550             if (fd && fd.semanticRun >= PASS.semanticdone)
6551                 return;
6552 
6553             Expression e = new FuncExp(ds.loc, ds.aliassym);
6554             e = e.expressionSemantic(sc);
6555             if (e.op == TOK.function_)
6556             {
6557                 FuncExp fe = cast(FuncExp)e;
6558                 ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;
6559             }
6560             else
6561             {
6562                 ds.aliassym = null;
6563                 ds.type = Type.terror;
6564             }
6565             return;
6566         }
6567 
6568         if (ds.aliassym.isTemplateInstance())
6569             ds.aliassym.dsymbolSemantic(sc);
6570         return;
6571     }
6572     ds.inuse = 1;
6573 
6574     // Given:
6575     //  alias foo.bar.abc def;
6576     // it is not knowable from the syntax whether this is an alias
6577     // for a type or an alias for a symbol. It is up to the semantic()
6578     // pass to distinguish.
6579     // If it is a type, then type is set and getType() will return that
6580     // type. If it is a symbol, then aliassym is set and type is NULL -
6581     // toAlias() will return aliasssym.
6582 
6583     uint errors = global.errors;
6584     Type oldtype = ds.type;
6585 
6586     // Ungag errors when not instantiated DeclDefs scope alias
6587     auto ungag = Ungag(global.gag);
6588     //printf("%s parent = %s, gag = %d, instantiated = %d\n", toChars(), parent, global.gag, isInstantiated());
6589     if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration())
6590     {
6591         //printf("%s type = %s\n", toPrettyChars(), type.toChars());
6592         global.gag = 0;
6593     }
6594 
6595     // https://issues.dlang.org/show_bug.cgi?id=18480
6596     // Detect `alias sym = sym;` to prevent creating loops in overload overnext lists.
6597     // Selective imports are allowed to alias to the same name `import mod : sym=sym`.
6598     if (ds.type.ty == Tident && !ds._import)
6599     {
6600         auto tident = cast(TypeIdentifier)ds.type;
6601         if (tident.ident is ds.ident && !tident.idents.dim)
6602         {
6603             error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set",
6604                 ds.ident.toChars(), tident.ident.toChars());
6605             ds.type = Type.terror;
6606         }
6607     }
6608     /* This section is needed because Type.resolve() will:
6609      *   const x = 3;
6610      *   alias y = x;
6611      * try to convert identifier x to 3.
6612      */
6613     auto s = ds.type.toDsymbol(sc);
6614     if (errors != global.errors)
6615     {
6616         s = null;
6617         ds.type = Type.terror;
6618     }
6619     if (s && s == ds)
6620     {
6621         ds.error("cannot resolve");
6622         s = null;
6623         ds.type = Type.terror;
6624     }
6625     if (!s || !s.isEnumMember())
6626     {
6627         Type t;
6628         Expression e;
6629         Scope* sc2 = sc;
6630         if (ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.disable))
6631         {
6632             // For 'ref' to be attached to function types, and picked
6633             // up by Type.resolve(), it has to go into sc.
6634             sc2 = sc.push();
6635             sc2.stc |= ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6636         }
6637         ds.type = ds.type.addSTC(ds.storage_class);
6638         ds.type.resolve(ds.loc, sc2, &e, &t, &s);
6639         if (sc2 != sc)
6640             sc2.pop();
6641 
6642         if (e)  // Try to convert Expression to Dsymbol
6643         {
6644             // TupleExp is naturally converted to a TupleDeclaration
6645             if (auto te = e.isTupleExp())
6646                 s = new TupleDeclaration(te.loc, ds.ident, cast(Objects*)te.exps);
6647             else
6648             {
6649                 s = getDsymbol(e);
6650                 if (!s)
6651                 {
6652                     if (e.op != TOK.error)
6653                         ds.error("cannot alias an expression `%s`", e.toChars());
6654                     t = Type.terror;
6655                 }
6656             }
6657         }
6658         ds.type = t;
6659     }
6660     if (s == ds)
6661     {
6662         assert(global.errors);
6663         ds.type = Type.terror;
6664         s = null;
6665     }
6666     if (!s) // it's a type alias
6667     {
6668         //printf("alias %s resolved to type %s\n", toChars(), type.toChars());
6669         ds.type = ds.type.typeSemantic(ds.loc, sc);
6670         ds.aliassym = null;
6671     }
6672     else    // it's a symbolic alias
6673     {
6674         //printf("alias %s resolved to %s %s\n", toChars(), s.kind(), s.toChars());
6675         ds.type = null;
6676         ds.aliassym = s;
6677     }
6678     if (global.gag && errors != global.errors)
6679     {
6680         ds.type = Type.terror;
6681         ds.aliassym = null;
6682     }
6683     ds.inuse = 0;
6684     ds.semanticRun = PASS.semanticdone;
6685 
6686     if (auto sx = ds.overnext)
6687     {
6688         ds.overnext = null;
6689         if (!ds.overloadInsert(sx))
6690             ScopeDsymbol.multiplyDefined(Loc.initial, sx, ds);
6691     }
6692 }