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