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