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