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