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