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