Home | History | Annotate | Line # | Download | only in dmd
dsymbolsem.d revision 1.1
      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 
     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  */
    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  */
    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 
    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.
    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;
    212     this(Scope* sc)
    213     {
    214         this.sc = sc;
    215     }
    216 
    217     // Save the scope and defer semantic analysis on the Dsymbol.
    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 
    225     override void visit(Dsymbol dsym)
    226     {
    227         dsym.error("%p has no semantic routine", dsym);
    228     }
    229 
    230     override void visit(ScopeDsymbol) { }
    231     override void visit(Declaration) { }
    232 
    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 
    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 
    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 
    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 
   1184     override void visit(TypeInfoDeclaration dsym)
   1185     {
   1186         assert(dsym._linkage == LINK.c);
   1187     }
   1188 
   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 
   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 
   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 
   1434     override void visit(AttribDeclaration atd)
   1435     {
   1436         attribSemantic(atd);
   1437     }
   1438 
   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 
   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 
   1812     override void visit(StaticIfDeclaration sid)
   1813     {
   1814         attribSemantic(sid);
   1815     }
   1816 
   1817     override void visit(StaticForeachDeclaration sfd)
   1818     {
   1819         attribSemantic(sfd);
   1820     }
   1821 
   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      */
   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 
   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 
   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 
   1942     override void visit(StaticAssert sa)
   1943     {
   1944         if (sa.semanticRun < PASS.semanticdone)
   1945             sa.semanticRun = PASS.semanticdone;
   1946     }
   1947 
   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 
   1955     override void visit(VersionSymbol vs)
   1956     {
   1957         if (vs.semanticRun < PASS.semanticdone)
   1958             vs.semanticRun = PASS.semanticdone;
   1959     }
   1960 
   1961     override void visit(Package pkg)
   1962     {
   1963         if (pkg.semanticRun < PASS.semanticdone)
   1964             pkg.semanticRun = PASS.semanticdone;
   1965     }
   1966 
   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 
   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 
   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 
   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 
   2616     override void visit(TemplateInstance ti)
   2617     {
   2618         templateInstanceSemantic(ti, sc, null);
   2619     }
   2620 
   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 
   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 
   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.
   3967     override void visit(FuncDeclaration funcdecl)
   3968     {
   3969         funcDeclarationSemantic(funcdecl);
   3970     }
   3971 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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  */
   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 
   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
   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
   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
   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  */
   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  */
   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
   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