"Fossies" - the Fresh Open Source Software Archive

Member "dmd2/src/dmd/dmd/dsymbolsem.d" (20 Nov 2020, 247730 Bytes) of package /linux/misc/dmd.2.094.2.linux.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) D source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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-2020 by The D Language Foundation, All Rights Reserved
    6  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
    7  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
    8  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d)
    9  * Documentation:  https://dlang.org/phobos/dmd_dsymbolsem.html
   10  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dsymbolsem.d
   11  */
   12 
   13 module dmd.dsymbolsem;
   14 
   15 import core.stdc.stdio;
   16 import core.stdc.string;
   17 
   18 import dmd.aggregate;
   19 import dmd.aliasthis;
   20 import dmd.arraytypes;
   21 import dmd.astcodegen;
   22 import dmd.attrib;
   23 import dmd.blockexit;
   24 import dmd.clone;
   25 import dmd.compiler;
   26 import dmd.dcast;
   27 import dmd.dclass;
   28 import dmd.declaration;
   29 import dmd.denum;
   30 import dmd.dimport;
   31 import dmd.dinterpret;
   32 import dmd.dmangle;
   33 import dmd.dmodule;
   34 import dmd.dscope;
   35 import dmd.dstruct;
   36 import dmd.dsymbol;
   37 import dmd.dtemplate;
   38 import dmd.dversion;
   39 import dmd.errors;
   40 import dmd.escape;
   41 import dmd.expression;
   42 import dmd.expressionsem;
   43 import dmd.func;
   44 import dmd.globals;
   45 import dmd.id;
   46 import dmd.identifier;
   47 import dmd.init;
   48 import dmd.initsem;
   49 import dmd.hdrgen;
   50 import dmd.mtype;
   51 import dmd.nogc;
   52 import dmd.nspace;
   53 import dmd.objc;
   54 import dmd.opover;
   55 import dmd.parse;
   56 import dmd.root.filename;
   57 import dmd.root.outbuffer;
   58 import dmd.root.rmem;
   59 import dmd.root.rootobject;
   60 import dmd.semantic2;
   61 import dmd.semantic3;
   62 import dmd.sideeffect;
   63 import dmd.statementsem;
   64 import dmd.staticassert;
   65 import dmd.tokens;
   66 import dmd.utf;
   67 import dmd.utils;
   68 import dmd.statement;
   69 import dmd.target;
   70 import dmd.templateparamsem;
   71 import dmd.typesem;
   72 import dmd.visitor;
   73 
   74 enum LOG = false;
   75 
   76 /*****************************************
   77  * Create inclusive postblit for struct by aggregating
   78  * all the postblits in postblits[] with the postblits for
   79  * all the members.
   80  * Note the close similarity with AggregateDeclaration::buildDtor(),
   81  * and the ordering changes (runs forward instead of backwards).
   82  */
   83 private FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc)
   84 {
   85     //printf("StructDeclaration::buildPostBlit() %s\n", sd.toChars());
   86     if (sd.isUnionDeclaration())
   87         return null;
   88 
   89     // by default, the storage class of the created postblit
   90     StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
   91     Loc declLoc = sd.postblits.dim ? sd.postblits[0].loc : sd.loc;
   92     Loc loc; // internal code should have no loc to prevent coverage
   93 
   94     // if any of the postblits are disabled, then the generated postblit
   95     // will be disabled
   96     for (size_t i = 0; i < sd.postblits.dim; i++)
   97     {
   98         stc |= sd.postblits[i].storage_class & STC.disable;
   99     }
  100 
  101     VarDeclaration[] fieldsToDestroy;
  102     auto postblitCalls = new Statements();
  103     // iterate through all the struct fields that are not disabled
  104     for (size_t i = 0; i < sd.fields.dim && !(stc & STC.disable); i++)
  105     {
  106         auto structField = sd.fields[i];
  107         if (structField.storage_class & STC.ref_)
  108             continue;
  109         if (structField.overlapped)
  110             continue;
  111         // if it's a struct declaration or an array of structs
  112         Type tv = structField.type.baseElemOf();
  113         if (tv.ty != Tstruct)
  114             continue;
  115         auto sdv = (cast(TypeStruct)tv).sym;
  116         // which has a postblit declaration
  117         if (!sdv.postblit)
  118             continue;
  119         assert(!sdv.isUnionDeclaration());
  120 
  121         // if this field's postblit is not `nothrow`, add a `scope(failure)`
  122         // block to destroy any prior successfully postblitted fields should
  123         // this field's postblit fail
  124         if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow)
  125         {
  126              // create a list of destructors that need to be called
  127             Expression[] dtorCalls;
  128             foreach(sf; fieldsToDestroy)
  129             {
  130                 Expression ex;
  131                 tv = sf.type.toBasetype();
  132                 if (tv.ty == Tstruct)
  133                 {
  134                     // this.v.__xdtor()
  135 
  136                     ex = new ThisExp(loc);
  137                     ex = new DotVarExp(loc, ex, sf);
  138 
  139                     // This is a hack so we can call destructors on const/immutable objects.
  140                     ex = new AddrExp(loc, ex);
  141                     ex = new CastExp(loc, ex, sf.type.mutableOf().pointerTo());
  142                     ex = new PtrExp(loc, ex);
  143                     if (stc & STC.safe)
  144                         stc = (stc & ~STC.safe) | STC.trusted;
  145 
  146                     auto sfv = (cast(TypeStruct)sf.type.baseElemOf()).sym;
  147 
  148                     ex = new DotVarExp(loc, ex, sfv.dtor, false);
  149                     ex = new CallExp(loc, ex);
  150 
  151                     dtorCalls ~= ex;
  152                 }
  153                 else
  154                 {
  155                     // _ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
  156 
  157                     const length = tv.numberOfElems(loc);
  158 
  159                     ex = new ThisExp(loc);
  160                     ex = new DotVarExp(loc, ex, sf);
  161 
  162                     // This is a hack so we can call destructors on const/immutable objects.
  163                     ex = new DotIdExp(loc, ex, Id.ptr);
  164                     ex = new CastExp(loc, ex, sdv.type.pointerTo());
  165                     if (stc & STC.safe)
  166                         stc = (stc & ~STC.safe) | STC.trusted;
  167 
  168                     auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
  169                                                     new IntegerExp(loc, length, Type.tsize_t));
  170                     // Prevent redundant bounds check
  171                     se.upperIsInBounds = true;
  172                     se.lowerIsLessThanUpper = true;
  173 
  174                     ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se);
  175 
  176                     dtorCalls ~= ex;
  177                 }
  178             }
  179             fieldsToDestroy = [];
  180 
  181             // aggregate the destructor calls
  182             auto dtors = new Statements();
  183             foreach_reverse(dc; dtorCalls)
  184             {
  185                 dtors.push(new ExpStatement(loc, dc));
  186             }
  187 
  188             // put destructor calls in a `scope(failure)` block
  189             postblitCalls.push(new ScopeGuardStatement(loc, TOK.onScopeFailure, new CompoundStatement(loc, dtors)));
  190         }
  191 
  192         // perform semantic on the member postblit in order to
  193         // be able to aggregate it later on with the rest of the
  194         // postblits
  195         sdv.postblit.functionSemantic();
  196 
  197         stc = mergeFuncAttrs(stc, sdv.postblit);
  198         stc = mergeFuncAttrs(stc, sdv.dtor);
  199 
  200         // if any of the struct member fields has disabled
  201         // its postblit, then `sd` is not copyable, so no
  202         // postblit is generated
  203         if (stc & STC.disable)
  204         {
  205             postblitCalls.setDim(0);
  206             break;
  207         }
  208 
  209         Expression ex;
  210         tv = structField.type.toBasetype();
  211         if (tv.ty == Tstruct)
  212         {
  213             // this.v.__xpostblit()
  214 
  215             ex = new ThisExp(loc);
  216             ex = new DotVarExp(loc, ex, structField);
  217 
  218             // This is a hack so we can call postblits on const/immutable objects.
  219             ex = new AddrExp(loc, ex);
  220             ex = new CastExp(loc, ex, structField.type.mutableOf().pointerTo());
  221             ex = new PtrExp(loc, ex);
  222             if (stc & STC.safe)
  223                 stc = (stc & ~STC.safe) | STC.trusted;
  224 
  225             ex = new DotVarExp(loc, ex, sdv.postblit, false);
  226             ex = new CallExp(loc, ex);
  227         }
  228         else
  229         {
  230             // _ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])
  231 
  232             const length = tv.numberOfElems(loc);
  233             if (length == 0)
  234                 continue;
  235 
  236             ex = new ThisExp(loc);
  237             ex = new DotVarExp(loc, ex, structField);
  238 
  239             // This is a hack so we can call postblits on const/immutable objects.
  240             ex = new DotIdExp(loc, ex, Id.ptr);
  241             ex = new CastExp(loc, ex, sdv.type.pointerTo());
  242             if (stc & STC.safe)
  243                 stc = (stc & ~STC.safe) | STC.trusted;
  244 
  245             auto se = new SliceExp(loc, ex, new IntegerExp(loc, 0, Type.tsize_t),
  246                                             new IntegerExp(loc, length, Type.tsize_t));
  247             // Prevent redundant bounds check
  248             se.upperIsInBounds = true;
  249             se.lowerIsLessThanUpper = true;
  250             ex = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayPostblit), se);
  251         }
  252         postblitCalls.push(new ExpStatement(loc, ex)); // combine in forward order
  253 
  254         /* https://issues.dlang.org/show_bug.cgi?id=10972
  255          * When subsequent field postblit calls fail,
  256          * this field should be destructed for Exception Safety.
  257          */
  258         if (sdv.dtor)
  259         {
  260             sdv.dtor.functionSemantic();
  261 
  262             // keep a list of fields that need to be destroyed in case
  263             // of a future postblit failure
  264             fieldsToDestroy ~= structField;
  265         }
  266     }
  267 
  268     void checkShared()
  269     {
  270         if (sd.type.isShared())
  271             stc |= STC.shared_;
  272     }
  273 
  274     // Build our own "postblit" which executes a, but only if needed.
  275     if (postblitCalls.dim || (stc & STC.disable))
  276     {
  277         //printf("Building __fieldPostBlit()\n");
  278         checkShared();
  279         auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit);
  280         dd.generated = true;
  281         dd.storage_class |= STC.inference;
  282         dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls);
  283         sd.postblits.shift(dd);
  284         sd.members.push(dd);
  285         dd.dsymbolSemantic(sc);
  286     }
  287 
  288     // create __xpostblit, which is the generated postblit
  289     FuncDeclaration xpostblit = null;
  290     switch (sd.postblits.dim)
  291     {
  292     case 0:
  293         break;
  294 
  295     case 1:
  296         xpostblit = sd.postblits[0];
  297         break;
  298 
  299     default:
  300         Expression e = null;
  301         stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc;
  302         for (size_t i = 0; i < sd.postblits.dim; i++)
  303         {
  304             auto fd = sd.postblits[i];
  305             stc = mergeFuncAttrs(stc, fd);
  306             if (stc & STC.disable)
  307             {
  308                 e = null;
  309                 break;
  310             }
  311             Expression ex = new ThisExp(loc);
  312             ex = new DotVarExp(loc, ex, fd, false);
  313             ex = new CallExp(loc, ex);
  314             e = Expression.combine(e, ex);
  315         }
  316 
  317         checkShared();
  318         auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit);
  319         dd.generated = true;
  320         dd.storage_class |= STC.inference;
  321         dd.fbody = new ExpStatement(loc, e);
  322         sd.members.push(dd);
  323         dd.dsymbolSemantic(sc);
  324         xpostblit = dd;
  325         break;
  326     }
  327 
  328     // Add an __xpostblit alias to make the inclusive postblit accessible
  329     if (xpostblit)
  330     {
  331         auto _alias = new AliasDeclaration(Loc.initial, Id.__xpostblit, xpostblit);
  332         _alias.dsymbolSemantic(sc);
  333         sd.members.push(_alias);
  334         _alias.addMember(sc, sd); // add to symbol table
  335     }
  336     return xpostblit;
  337 }
  338 
  339 /**
  340  * Generates a copy constructor declaration with the specified storage
  341  * class for the parameter and the function.
  342  *
  343  * Params:
  344  *  sd = the `struct` that contains the copy constructor
  345  *  paramStc = the storage class of the copy constructor parameter
  346  *  funcStc = the storage class for the copy constructor declaration
  347  *
  348  * Returns:
  349  *  The copy constructor declaration for struct `sd`.
  350  */
  351 private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc)
  352 {
  353     auto fparams = new Parameters();
  354     auto structType = sd.type;
  355     fparams.push(new Parameter(paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
  356     ParameterList pList = ParameterList(fparams);
  357     auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_);
  358     auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true);
  359     ccd.storage_class |= funcStc;
  360     ccd.storage_class |= STC.inference;
  361     ccd.generated = true;
  362     return ccd;
  363 }
  364 
  365 /**
  366  * Generates a trivial copy constructor body that simply does memberwise
  367  * initialization:
  368  *
  369  *    this.field1 = rhs.field1;
  370  *    this.field2 = rhs.field2;
  371  *    ...
  372  *
  373  * Params:
  374  *  sd = the `struct` declaration that contains the copy constructor
  375  *
  376  * Returns:
  377  *  A `CompoundStatement` containing the body of the copy constructor.
  378  */
  379 private Statement generateCopyCtorBody(StructDeclaration sd)
  380 {
  381     Loc loc;
  382     Expression e;
  383     foreach (v; sd.fields)
  384     {
  385         auto ec = new AssignExp(loc,
  386             new DotVarExp(loc, new ThisExp(loc), v),
  387             new DotVarExp(loc, new IdentifierExp(loc, Id.p), v));
  388         e = Expression.combine(e, ec);
  389         //printf("e.toChars = %s\n", e.toChars());
  390     }
  391     Statement s1 = new ExpStatement(loc, e);
  392     return new CompoundStatement(loc, s1);
  393 }
  394 
  395 /**
  396  * Generates a copy constructor for a specified `struct` sd if
  397  * the following conditions are met:
  398  *
  399  * 1. sd does not define a copy constructor
  400  * 2. at least one field of sd defines a copy constructor
  401  *
  402  * If the above conditions are met, the following copy constructor
  403  * is generated:
  404  *
  405  * this(ref return scope inout(S) rhs) inout
  406  * {
  407  *    this.field1 = rhs.field1;
  408  *    this.field2 = rhs.field2;
  409  *    ...
  410  * }
  411  *
  412  * Params:
  413  *  sd = the `struct` for which the copy constructor is generated
  414  *  sc = the scope where the copy constructor is generated
  415  *
  416  * Returns:
  417  *  `true` if `struct` sd defines a copy constructor (explicitly or generated),
  418  *  `false` otherwise.
  419  */
  420 private bool buildCopyCtor(StructDeclaration sd, Scope* sc)
  421 {
  422     if (global.errors)
  423         return false;
  424 
  425     bool hasPostblit;
  426     if (sd.postblit && !sd.postblit.isDisabled())
  427         hasPostblit = true;
  428 
  429     auto ctor = sd.search(sd.loc, Id.ctor);
  430     CtorDeclaration cpCtor;
  431     CtorDeclaration rvalueCtor;
  432     if (ctor)
  433     {
  434         if (ctor.isOverloadSet())
  435             return false;
  436         if (auto td = ctor.isTemplateDeclaration())
  437             ctor = td.funcroot;
  438     }
  439 
  440     if (!ctor)
  441         goto LcheckFields;
  442 
  443     overloadApply(ctor, (Dsymbol s)
  444     {
  445         if (s.isTemplateDeclaration())
  446             return 0;
  447         auto ctorDecl = s.isCtorDeclaration();
  448         assert(ctorDecl);
  449         if (ctorDecl.isCpCtor)
  450         {
  451             if (!cpCtor)
  452                 cpCtor = ctorDecl;
  453             return 0;
  454         }
  455 
  456         auto tf = ctorDecl.type.toTypeFunction();
  457         const dim = tf.parameterList.length;
  458         if (dim == 1)
  459         {
  460             auto param = tf.parameterList[0];
  461             if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
  462             {
  463                 rvalueCtor = ctorDecl;
  464             }
  465         }
  466         return 0;
  467     });
  468 
  469     if (cpCtor && rvalueCtor)
  470     {
  471         .error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars());
  472         errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
  473         errorSupplemental(cpCtor.loc, "copy constructor defined here");
  474         return true;
  475     }
  476     else if (cpCtor)
  477     {
  478         return !hasPostblit;
  479     }
  480 
  481 LcheckFields:
  482     VarDeclaration fieldWithCpCtor;
  483     // see if any struct members define a copy constructor
  484     foreach (v; sd.fields)
  485     {
  486         if (v.storage_class & STC.ref_)
  487             continue;
  488         if (v.overlapped)
  489             continue;
  490 
  491         auto ts = v.type.baseElemOf().isTypeStruct();
  492         if (!ts)
  493             continue;
  494         if (ts.sym.hasCopyCtor)
  495         {
  496             fieldWithCpCtor = v;
  497             break;
  498         }
  499     }
  500 
  501     if (fieldWithCpCtor && rvalueCtor)
  502     {
  503         .error(sd.loc, "`struct %s` may not define a rvalue constructor and have fields with copy constructors", sd.toChars());
  504         errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
  505         errorSupplemental(fieldWithCpCtor.loc, "field with copy constructor defined here");
  506         return false;
  507     }
  508     else if (!fieldWithCpCtor)
  509         return false;
  510 
  511     if (hasPostblit)
  512         return false;
  513 
  514     //printf("generating copy constructor for %s\n", sd.toChars());
  515     const MOD paramMod = MODFlags.wild;
  516     const MOD funcMod = MODFlags.wild;
  517     auto ccd = generateCopyCtorDeclaration(sd, ModToStc(paramMod), ModToStc(funcMod));
  518     auto copyCtorBody = generateCopyCtorBody(sd);
  519     ccd.fbody = copyCtorBody;
  520     sd.members.push(ccd);
  521     ccd.addMember(sc, sd);
  522     const errors = global.startGagging();
  523     Scope* sc2 = sc.push();
  524     sc2.stc = 0;
  525     sc2.linkage = LINK.d;
  526     ccd.dsymbolSemantic(sc2);
  527     ccd.semantic2(sc2);
  528     ccd.semantic3(sc2);
  529     //printf("ccd semantic: %s\n", ccd.type.toChars());
  530     sc2.pop();
  531     if (global.endGagging(errors) || sd.isUnionDeclaration())
  532     {
  533         ccd.storage_class |= STC.disable;
  534         ccd.fbody = null;
  535     }
  536     return true;
  537 }
  538 
  539 private uint setMangleOverride(Dsymbol s, const(char)[] sym)
  540 {
  541     if (s.isFuncDeclaration() || s.isVarDeclaration())
  542     {
  543         s.isDeclaration().mangleOverride = sym;
  544         return 1;
  545     }
  546 
  547     if (auto ad = s.isAttribDeclaration())
  548     {
  549         uint nestedCount = 0;
  550 
  551         ad.include(null).foreachDsymbol( (s) { nestedCount += setMangleOverride(s, sym); } );
  552 
  553         return nestedCount;
  554     }
  555     return 0;
  556 }
  557 
  558 /*************************************
  559  * Does semantic analysis on the public face of declarations.
  560  */
  561 extern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc)
  562 {
  563     scope v = new DsymbolSemanticVisitor(sc);
  564     dsym.accept(v);
  565 }
  566 
  567 structalign_t getAlignment(AlignDeclaration ad, Scope* sc)
  568 {
  569     if (ad.salign != ad.UNKNOWN)
  570         return ad.salign;
  571 
  572     if (!ad.ealign)
  573         return ad.salign = STRUCTALIGN_DEFAULT;
  574 
  575     sc = sc.startCTFE();
  576     ad.ealign = ad.ealign.expressionSemantic(sc);
  577     ad.ealign = resolveProperties(sc, ad.ealign);
  578     sc = sc.endCTFE();
  579     ad.ealign = ad.ealign.ctfeInterpret();
  580 
  581     if (ad.ealign.op == TOK.error)
  582         return ad.salign = STRUCTALIGN_DEFAULT;
  583 
  584     Type tb = ad.ealign.type.toBasetype();
  585     auto n = ad.ealign.toInteger();
  586 
  587     if (n < 1 || n & (n - 1) || structalign_t.max < n || !tb.isintegral())
  588     {
  589         error(ad.loc, "alignment must be an integer positive power of 2, not %s", ad.ealign.toChars());
  590         return ad.salign = STRUCTALIGN_DEFAULT;
  591     }
  592 
  593     return ad.salign = cast(structalign_t)n;
  594 }
  595 
  596 const(char)* getMessage(DeprecatedDeclaration dd)
  597 {
  598     if (auto sc = dd._scope)
  599     {
  600         dd._scope = null;
  601 
  602         sc = sc.startCTFE();
  603         dd.msg = dd.msg.expressionSemantic(sc);
  604         dd.msg = resolveProperties(sc, dd.msg);
  605         sc = sc.endCTFE();
  606         dd.msg = dd.msg.ctfeInterpret();
  607 
  608         if (auto se = dd.msg.toStringExp())
  609             dd.msgstr = se.toStringz().ptr;
  610         else
  611             dd.msg.error("compile time constant expected, not `%s`", dd.msg.toChars());
  612     }
  613     return dd.msgstr;
  614 }
  615 
  616 
  617 // Returns true if a contract can appear without a function body.
  618 package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
  619 {
  620     assert(!funcdecl.fbody);
  621 
  622     /* Contracts can only appear without a body when they are virtual
  623      * interface functions or abstract.
  624      */
  625     Dsymbol parent = funcdecl.toParent();
  626     InterfaceDeclaration id = parent.isInterfaceDeclaration();
  627 
  628     if (!funcdecl.isAbstract() &&
  629         (funcdecl.fensures || funcdecl.frequires) &&
  630         !(id && funcdecl.isVirtual()))
  631     {
  632         auto cd = parent.isClassDeclaration();
  633         if (!(cd && cd.isAbstract()))
  634             return false;
  635     }
  636     return true;
  637 }
  638 
  639 private extern(C++) final class DsymbolSemanticVisitor : Visitor
  640 {
  641     alias visit = Visitor.visit;
  642 
  643     Scope* sc;
  644     this(Scope* sc)
  645     {
  646         this.sc = sc;
  647     }
  648 
  649     // Save the scope and defer semantic analysis on the Dsymbol.
  650     private void deferDsymbolSemantic(Dsymbol s, Scope *scx)
  651     {
  652         s._scope = scx ? scx : sc.copy();
  653         s._scope.setNoFree();
  654         Module.addDeferredSemantic(s);
  655     }
  656 
  657     override void visit(Dsymbol dsym)
  658     {
  659         dsym.error("%p has no semantic routine", dsym);
  660     }
  661 
  662     override void visit(ScopeDsymbol) { }
  663     override void visit(Declaration) { }
  664 
  665     override void visit(AliasThis dsym)
  666     {
  667         if (dsym.semanticRun != PASS.init)
  668             return;
  669 
  670         if (dsym._scope)
  671         {
  672             sc = dsym._scope;
  673             dsym._scope = null;
  674         }
  675 
  676         if (!sc)
  677             return;
  678 
  679         dsym.semanticRun = PASS.semantic;
  680         dsym.isDeprecated_ = !!(sc.stc & STC.deprecated_);
  681 
  682         Dsymbol p = sc.parent.pastMixin();
  683         AggregateDeclaration ad = p.isAggregateDeclaration();
  684         if (!ad)
  685         {
  686             error(dsym.loc, "alias this can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
  687             return;
  688         }
  689 
  690         assert(ad.members);
  691         Dsymbol s = ad.search(dsym.loc, dsym.ident);
  692         if (!s)
  693         {
  694             s = sc.search(dsym.loc, dsym.ident, null);
  695             if (s)
  696                 error(dsym.loc, "`%s` is not a member of `%s`", s.toChars(), ad.toChars());
  697             else
  698                 error(dsym.loc, "undefined identifier `%s`", dsym.ident.toChars());
  699             return;
  700         }
  701         if (ad.aliasthis && s != ad.aliasthis)
  702         {
  703             error(dsym.loc, "there can be only one alias this");
  704             return;
  705         }
  706 
  707         /* disable the alias this conversion so the implicit conversion check
  708          * doesn't use it.
  709          */
  710         ad.aliasthis = null;
  711 
  712         Dsymbol sx = s;
  713         if (sx.isAliasDeclaration())
  714             sx = sx.toAlias();
  715         Declaration d = sx.isDeclaration();
  716         if (d && !d.isTupleDeclaration())
  717         {
  718             /* https://issues.dlang.org/show_bug.cgi?id=18429
  719              *
  720              * If the identifier in the AliasThis declaration
  721              * is defined later and is a voldemort type, we must
  722              * perform semantic on the declaration to deduce the type.
  723              */
  724             if (!d.type)
  725                 d.dsymbolSemantic(sc);
  726 
  727             Type t = d.type;
  728             assert(t);
  729             if (ad.type.implicitConvTo(t) > MATCH.nomatch)
  730             {
  731                 error(dsym.loc, "alias this is not reachable as `%s` already converts to `%s`", ad.toChars(), t.toChars());
  732             }
  733         }
  734 
  735         dsym.sym = s;
  736         // Restore alias this
  737         ad.aliasthis = dsym;
  738         dsym.semanticRun = PASS.semanticdone;
  739     }
  740 
  741     override void visit(AliasDeclaration dsym)
  742     {
  743         if (dsym.semanticRun >= PASS.semanticdone)
  744             return;
  745         assert(dsym.semanticRun <= PASS.semantic);
  746 
  747         dsym.storage_class |= sc.stc & STC.deprecated_;
  748         dsym.protection = sc.protection;
  749         dsym.userAttribDecl = sc.userAttribDecl;
  750 
  751         if (!sc.func && dsym.inNonRoot())
  752             return;
  753 
  754         aliasSemantic(dsym, sc);
  755     }
  756 
  757     override void visit(VarDeclaration dsym)
  758     {
  759         version (none)
  760         {
  761             printf("VarDeclaration::semantic('%s', parent = '%s') sem = %d\n",
  762                    dsym.toChars(), sc.parent ? sc.parent.toChars() : null, dsym.semanticRun);
  763             printf(" type = %s\n", dsym.type ? dsym.type.toChars() : "null");
  764             printf(" stc = x%llx\n", dsym.storage_class);
  765             printf(" storage_class = x%llx\n", dsym.storage_class);
  766             printf("linkage = %d\n", dsym.linkage);
  767             //if (strcmp(toChars(), "mul") == 0) assert(0);
  768         }
  769         //if (semanticRun > PASS.init)
  770         //    return;
  771         //semanticRun = PSSsemantic;
  772 
  773         if (dsym.semanticRun >= PASS.semanticdone)
  774             return;
  775 
  776         if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
  777             dsym.overlapped = true;
  778 
  779         Scope* scx = null;
  780         if (dsym._scope)
  781         {
  782             sc = dsym._scope;
  783             scx = sc;
  784             dsym._scope = null;
  785         }
  786 
  787         if (!sc)
  788             return;
  789 
  790         dsym.semanticRun = PASS.semantic;
  791 
  792         /* Pick up storage classes from context, but except synchronized,
  793          * override, abstract, and final.
  794          */
  795         dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));
  796         if (dsym.storage_class & STC.extern_ && dsym._init)
  797             dsym.error("extern symbols cannot have initializers");
  798 
  799         dsym.userAttribDecl = sc.userAttribDecl;
  800         dsym.cppnamespace = sc.namespace;
  801 
  802         AggregateDeclaration ad = dsym.isThis();
  803         if (ad)
  804             dsym.storage_class |= ad.storage_class & STC.TYPECTOR;
  805 
  806         /* If auto type inference, do the inference
  807          */
  808         int inferred = 0;
  809         if (!dsym.type)
  810         {
  811             dsym.inuse++;
  812 
  813             // Infering the type requires running semantic,
  814             // so mark the scope as ctfe if required
  815             bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
  816             if (needctfe)
  817             {
  818                 sc.flags |= SCOPE.condition;
  819                 sc = sc.startCTFE();
  820             }
  821             //printf("inferring type for %s with init %s\n", dsym.toChars(), dsym._init.toChars());
  822             dsym._init = dsym._init.inferType(sc);
  823             dsym.type = dsym._init.initializerToExpression().type;
  824             if (needctfe)
  825                 sc = sc.endCTFE();
  826 
  827             dsym.inuse--;
  828             inferred = 1;
  829 
  830             /* This is a kludge to support the existing syntax for RAII
  831              * declarations.
  832              */
  833             dsym.storage_class &= ~STC.auto_;
  834             dsym.originalType = dsym.type.syntaxCopy();
  835         }
  836         else
  837         {
  838             if (!dsym.originalType)
  839                 dsym.originalType = dsym.type.syntaxCopy();
  840 
  841             /* Prefix function attributes of variable declaration can affect
  842              * its type:
  843              *      pure nothrow void function() fp;
  844              *      static assert(is(typeof(fp) == void function() pure nothrow));
  845              */
  846             Scope* sc2 = sc.push();
  847             sc2.stc |= (dsym.storage_class & STC.FUNCATTR);
  848             dsym.inuse++;
  849             dsym.type = dsym.type.typeSemantic(dsym.loc, sc2);
  850             dsym.inuse--;
  851             sc2.pop();
  852         }
  853         //printf(" semantic type = %s\n", dsym.type ? dsym.type.toChars() : "null");
  854         if (dsym.type.ty == Terror)
  855             dsym.errors = true;
  856 
  857         dsym.type.checkDeprecated(dsym.loc, sc);
  858         dsym.linkage = sc.linkage;
  859         dsym.parent = sc.parent;
  860         //printf("this = %p, parent = %p, '%s'\n", dsym, dsym.parent, dsym.parent.toChars());
  861         dsym.protection = sc.protection;
  862 
  863         /* If scope's alignment is the default, use the type's alignment,
  864          * otherwise the scope overrrides.
  865          */
  866         dsym.alignment = sc.alignment();
  867         if (dsym.alignment == STRUCTALIGN_DEFAULT)
  868             dsym.alignment = dsym.type.alignment(); // use type's alignment
  869 
  870         //printf("sc.stc = %x\n", sc.stc);
  871         //printf("storage_class = x%x\n", storage_class);
  872 
  873         if (global.params.vcomplex)
  874             dsym.type.checkComplexTransition(dsym.loc, sc);
  875 
  876         // Calculate type size + safety checks
  877         if (sc.func && !sc.intypeof)
  878         {
  879             if (dsym.storage_class & STC.gshared && !dsym.isMember())
  880             {
  881                 if (sc.func.setUnsafe())
  882                     dsym.error("__gshared not allowed in safe functions; use shared");
  883             }
  884         }
  885 
  886         Dsymbol parent = dsym.toParent();
  887 
  888         Type tb = dsym.type.toBasetype();
  889         Type tbn = tb.baseElemOf();
  890         if (tb.ty == Tvoid && !(dsym.storage_class & STC.lazy_))
  891         {
  892             if (inferred)
  893             {
  894                 dsym.error("type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", dsym.type.toChars(), dsym._init.toChars());
  895             }
  896             else
  897                 dsym.error("variables cannot be of type `void`");
  898             dsym.type = Type.terror;
  899             tb = dsym.type;
  900         }
  901         if (tb.ty == Tfunction)
  902         {
  903             dsym.error("cannot be declared to be a function");
  904             dsym.type = Type.terror;
  905             tb = dsym.type;
  906         }
  907         if (auto ts = tb.isTypeStruct())
  908         {
  909             if (!ts.sym.members)
  910             {
  911                 dsym.error("no definition of struct `%s`", ts.toChars());
  912             }
  913         }
  914         if ((dsym.storage_class & STC.auto_) && !inferred)
  915             dsym.error("storage class `auto` has no effect if type is not inferred, did you mean `scope`?");
  916 
  917         if (auto tt = tb.isTypeTuple())
  918         {
  919             /* Instead, declare variables for each of the tuple elements
  920              * and add those.
  921              */
  922             size_t nelems = Parameter.dim(tt.arguments);
  923             Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression() : null;
  924             if (ie)
  925                 ie = ie.expressionSemantic(sc);
  926             if (nelems > 0 && ie)
  927             {
  928                 auto iexps = new Expressions();
  929                 iexps.push(ie);
  930                 auto exps = new Expressions();
  931                 for (size_t pos = 0; pos < iexps.dim; pos++)
  932                 {
  933                 Lexpand1:
  934                     Expression e = (*iexps)[pos];
  935                     Parameter arg = Parameter.getNth(tt.arguments, pos);
  936                     arg.type = arg.type.typeSemantic(dsym.loc, sc);
  937                     //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
  938                     //printf("e = (%s %s, %s), ", Token::tochars[e.op], e.toChars(), e.type.toChars());
  939                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
  940 
  941                     if (e != ie)
  942                     {
  943                         if (iexps.dim > nelems)
  944                             goto Lnomatch;
  945                         if (e.type.implicitConvTo(arg.type))
  946                             continue;
  947                     }
  948 
  949                     if (e.op == TOK.tuple)
  950                     {
  951                         TupleExp te = cast(TupleExp)e;
  952                         if (iexps.dim - 1 + te.exps.dim > nelems)
  953                             goto Lnomatch;
  954 
  955                         iexps.remove(pos);
  956                         iexps.insert(pos, te.exps);
  957                         (*iexps)[pos] = Expression.combine(te.e0, (*iexps)[pos]);
  958                         goto Lexpand1;
  959                     }
  960                     else if (isAliasThisTuple(e))
  961                     {
  962                         auto v = copyToTemp(0, "__tup", e);
  963                         v.dsymbolSemantic(sc);
  964                         auto ve = new VarExp(dsym.loc, v);
  965                         ve.type = e.type;
  966 
  967                         exps.setDim(1);
  968                         (*exps)[0] = ve;
  969                         expandAliasThisTuples(exps, 0);
  970 
  971                         for (size_t u = 0; u < exps.dim; u++)
  972                         {
  973                         Lexpand2:
  974                             Expression ee = (*exps)[u];
  975                             arg = Parameter.getNth(tt.arguments, pos + u);
  976                             arg.type = arg.type.typeSemantic(dsym.loc, sc);
  977                             //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
  978                             //printf("ee = (%s %s, %s), ", Token::tochars[ee.op], ee.toChars(), ee.type.toChars());
  979                             //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
  980 
  981                             size_t iexps_dim = iexps.dim - 1 + exps.dim;
  982                             if (iexps_dim > nelems)
  983                                 goto Lnomatch;
  984                             if (ee.type.implicitConvTo(arg.type))
  985                                 continue;
  986 
  987                             if (expandAliasThisTuples(exps, u) != -1)
  988                                 goto Lexpand2;
  989                         }
  990 
  991                         if ((*exps)[0] != ve)
  992                         {
  993                             Expression e0 = (*exps)[0];
  994                             (*exps)[0] = new CommaExp(dsym.loc, new DeclarationExp(dsym.loc, v), e0);
  995                             (*exps)[0].type = e0.type;
  996 
  997                             iexps.remove(pos);
  998                             iexps.insert(pos, exps);
  999                             goto Lexpand1;
 1000                         }
 1001                     }
 1002                 }
 1003                 if (iexps.dim < nelems)
 1004                     goto Lnomatch;
 1005 
 1006                 ie = new TupleExp(dsym._init.loc, iexps);
 1007             }
 1008         Lnomatch:
 1009 
 1010             if (ie && ie.op == TOK.tuple)
 1011             {
 1012                 TupleExp te = cast(TupleExp)ie;
 1013                 size_t tedim = te.exps.dim;
 1014                 if (tedim != nelems)
 1015                 {
 1016                     error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
 1017                     for (size_t u = tedim; u < nelems; u++) // fill dummy expression
 1018                         te.exps.push(ErrorExp.get());
 1019                 }
 1020             }
 1021 
 1022             auto exps = new Objects(nelems);
 1023             for (size_t i = 0; i < nelems; i++)
 1024             {
 1025                 Parameter arg = Parameter.getNth(tt.arguments, i);
 1026 
 1027                 OutBuffer buf;
 1028                 buf.printf("__%s_field_%llu", dsym.ident.toChars(), cast(ulong)i);
 1029                 auto id = Identifier.idPool(buf[]);
 1030 
 1031                 Initializer ti;
 1032                 if (ie)
 1033                 {
 1034                     Expression einit = ie;
 1035                     if (ie.op == TOK.tuple)
 1036                     {
 1037                         TupleExp te = cast(TupleExp)ie;
 1038                         einit = (*te.exps)[i];
 1039                         if (i == 0)
 1040                             einit = Expression.combine(te.e0, einit);
 1041                     }
 1042                     ti = new ExpInitializer(einit.loc, einit);
 1043                 }
 1044                 else
 1045                     ti = dsym._init ? dsym._init.syntaxCopy() : null;
 1046 
 1047                 StorageClass storage_class = STC.temp | dsym.storage_class;
 1048                 if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter))
 1049                     storage_class |= arg.storageClass;
 1050                 auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);
 1051                 //printf("declaring field %s of type %s\n", v.toChars(), v.type.toChars());
 1052                 v.dsymbolSemantic(sc);
 1053 
 1054                 if (sc.scopesym)
 1055                 {
 1056                     //printf("adding %s to %s\n", v.toChars(), sc.scopesym.toChars());
 1057                     if (sc.scopesym.members)
 1058                         // Note this prevents using foreach() over members, because the limits can change
 1059                         sc.scopesym.members.push(v);
 1060                 }
 1061 
 1062                 Expression e = new DsymbolExp(dsym.loc, v);
 1063                 (*exps)[i] = e;
 1064             }
 1065             auto v2 = new TupleDeclaration(dsym.loc, dsym.ident, exps);
 1066             v2.parent = dsym.parent;
 1067             v2.isexp = true;
 1068             dsym.aliassym = v2;
 1069             dsym.semanticRun = PASS.semanticdone;
 1070             return;
 1071         }
 1072 
 1073         /* Storage class can modify the type
 1074          */
 1075         dsym.type = dsym.type.addStorageClass(dsym.storage_class);
 1076 
 1077         /* Adjust storage class to reflect type
 1078          */
 1079         if (dsym.type.isConst())
 1080         {
 1081             dsym.storage_class |= STC.const_;
 1082             if (dsym.type.isShared())
 1083                 dsym.storage_class |= STC.shared_;
 1084         }
 1085         else if (dsym.type.isImmutable())
 1086             dsym.storage_class |= STC.immutable_;
 1087         else if (dsym.type.isShared())
 1088             dsym.storage_class |= STC.shared_;
 1089         else if (dsym.type.isWild())
 1090             dsym.storage_class |= STC.wild;
 1091 
 1092         if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_))
 1093         {
 1094             if (stc == STC.final_)
 1095                 dsym.error("cannot be `final`, perhaps you meant `const`?");
 1096             else
 1097             {
 1098                 OutBuffer buf;
 1099                 stcToBuffer(&buf, stc);
 1100                 dsym.error("cannot be `%s`", buf.peekChars());
 1101             }
 1102             dsym.storage_class &= ~stc; // strip off
 1103         }
 1104 
 1105         // At this point we can add `scope` to the STC instead of `in`,
 1106         // because we are never going to use this variable's STC for user messages
 1107         if (dsym.storage_class & STC.in_ && global.params.previewIn)
 1108             dsym.storage_class |= STC.scope_;
 1109 
 1110         if (dsym.storage_class & STC.scope_)
 1111         {
 1112             StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.tls | STC.gshared);
 1113             if (stc)
 1114             {
 1115                 OutBuffer buf;
 1116                 stcToBuffer(&buf, stc);
 1117                 dsym.error("cannot be `scope` and `%s`", buf.peekChars());
 1118             }
 1119             else if (dsym.isMember())
 1120             {
 1121                 dsym.error("field cannot be `scope`");
 1122             }
 1123             else if (!dsym.type.hasPointers())
 1124             {
 1125                 dsym.storage_class &= ~STC.scope_;     // silently ignore; may occur in generic code
 1126             }
 1127         }
 1128 
 1129         if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.tls | STC.gshared | STC.ctfe))
 1130         {
 1131         }
 1132         else
 1133         {
 1134             AggregateDeclaration aad = parent.isAggregateDeclaration();
 1135             if (aad)
 1136             {
 1137                 if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer())
 1138                 {
 1139                     const(char)* s = (dsym.storage_class & STC.immutable_) ? "immutable" : "const";
 1140                     message(dsym.loc, "`%s.%s` is `%s` field", ad.toPrettyChars(), dsym.toChars(), s);
 1141                 }
 1142                 dsym.storage_class |= STC.field;
 1143                 if (auto ts = tbn.isTypeStruct())
 1144                     if (ts.sym.noDefaultCtor)
 1145                     {
 1146                         if (!dsym.isThisDeclaration() && !dsym._init)
 1147                             aad.noDefaultCtor = true;
 1148                     }
 1149             }
 1150 
 1151             InterfaceDeclaration id = parent.isInterfaceDeclaration();
 1152             if (id)
 1153             {
 1154                 dsym.error("field not allowed in interface");
 1155             }
 1156             else if (aad && aad.sizeok == Sizeok.done)
 1157             {
 1158                 dsym.error("cannot be further field because it will change the determined %s size", aad.toChars());
 1159             }
 1160 
 1161             /* Templates cannot add fields to aggregates
 1162              */
 1163             TemplateInstance ti = parent.isTemplateInstance();
 1164             if (ti)
 1165             {
 1166                 // Take care of nested templates
 1167                 while (1)
 1168                 {
 1169                     TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
 1170                     if (!ti2)
 1171                         break;
 1172                     ti = ti2;
 1173                 }
 1174                 // If it's a member template
 1175                 AggregateDeclaration ad2 = ti.tempdecl.isMember();
 1176                 if (ad2 && dsym.storage_class != STC.undefined_)
 1177                 {
 1178                     dsym.error("cannot use template to add field to aggregate `%s`", ad2.toChars());
 1179                 }
 1180             }
 1181         }
 1182 
 1183         if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)
 1184         {
 1185             dsym.error("only parameters or `foreach` declarations can be `ref`");
 1186         }
 1187 
 1188         if (dsym.type.hasWild())
 1189         {
 1190             if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg())
 1191             {
 1192                 dsym.error("only parameters or stack based variables can be `inout`");
 1193             }
 1194             FuncDeclaration func = sc.func;
 1195             if (func)
 1196             {
 1197                 if (func.fes)
 1198                     func = func.fes.func;
 1199                 bool isWild = false;
 1200                 for (FuncDeclaration fd = func; fd; fd = fd.toParentDecl().isFuncDeclaration())
 1201                 {
 1202                     if ((cast(TypeFunction)fd.type).iswild)
 1203                     {
 1204                         isWild = true;
 1205                         break;
 1206                     }
 1207                 }
 1208                 if (!isWild)
 1209                 {
 1210                     dsym.error("`inout` variables can only be declared inside `inout` functions");
 1211                 }
 1212             }
 1213         }
 1214 
 1215         if (!(dsym.storage_class & (STC.ctfe | STC.ref_ | STC.result)) &&
 1216             tbn.ty == Tstruct && (cast(TypeStruct)tbn).sym.noDefaultCtor)
 1217         {
 1218             if (!dsym._init)
 1219             {
 1220                 if (dsym.isField())
 1221                 {
 1222                     /* For fields, we'll check the constructor later to make sure it is initialized
 1223                      */
 1224                     dsym.storage_class |= STC.nodefaultctor;
 1225                 }
 1226                 else if (dsym.storage_class & STC.parameter)
 1227                 {
 1228                 }
 1229                 else
 1230                     dsym.error("default construction is disabled for type `%s`", dsym.type.toChars());
 1231             }
 1232         }
 1233 
 1234         FuncDeclaration fd = parent.isFuncDeclaration();
 1235         if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor))
 1236         {
 1237             if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.tls | STC.gshared) || !fd)
 1238             {
 1239                 dsym.error("globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`");
 1240             }
 1241 
 1242             // @@@DEPRECATED@@@  https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
 1243             // Deprecated in 2.087
 1244             // Remove this when the feature is removed from the language
 1245             if (0 &&          // deprecation disabled for now to accommodate existing extensive use
 1246                !(dsym.storage_class & STC.scope_))
 1247             {
 1248                 if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym)
 1249                     dsym.error("reference to `scope class` must be `scope`");
 1250             }
 1251         }
 1252 
 1253         // Calculate type size + safety checks
 1254         if (sc.func && !sc.intypeof)
 1255         {
 1256             if (dsym._init && dsym._init.isVoidInitializer() && dsym.type.hasPointers()) // get type size
 1257             {
 1258                 if (sc.func.setUnsafe())
 1259                     dsym.error("`void` initializers for pointers not allowed in safe functions");
 1260             }
 1261             else if (!dsym._init &&
 1262                      !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&
 1263                      dsym.type.hasVoidInitPointers())
 1264             {
 1265                 if (sc.func.setUnsafe())
 1266                     dsym.error("`void` initializers for pointers not allowed in safe functions");
 1267             }
 1268         }
 1269 
 1270         if ((!dsym._init || dsym._init.isVoidInitializer) && !fd)
 1271         {
 1272             // If not mutable, initializable by constructor only
 1273             dsym.storage_class |= STC.ctorinit;
 1274         }
 1275 
 1276         if (dsym._init)
 1277             dsym.storage_class |= STC.init; // remember we had an explicit initializer
 1278         else if (dsym.storage_class & STC.manifest)
 1279             dsym.error("manifest constants must have initializers");
 1280 
 1281         bool isBlit = false;
 1282         d_uns64 sz;
 1283         if (!dsym._init &&
 1284             !(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&
 1285             fd &&
 1286             (!(dsym.storage_class & (STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result)) ||
 1287              (dsym.storage_class & STC.out_)) &&
 1288             (sz = dsym.type.size()) != 0)
 1289         {
 1290             // Provide a default initializer
 1291 
 1292             //printf("Providing default initializer for '%s'\n", toChars());
 1293             if (sz == SIZE_INVALID && dsym.type.ty != Terror)
 1294                 dsym.error("size of type `%s` is invalid", dsym.type.toChars());
 1295 
 1296             Type tv = dsym.type;
 1297             while (tv.ty == Tsarray)    // Don't skip Tenum
 1298                 tv = tv.nextOf();
 1299             if (tv.needsNested())
 1300             {
 1301                 /* Nested struct requires valid enclosing frame pointer.
 1302                  * In StructLiteralExp::toElem(), it's calculated.
 1303                  */
 1304                 assert(tbn.ty == Tstruct);
 1305                 checkFrameAccess(dsym.loc, sc, tbn.isTypeStruct().sym);
 1306 
 1307                 Expression e = tv.defaultInitLiteral(dsym.loc);
 1308                 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
 1309                 e = e.expressionSemantic(sc);
 1310                 dsym._init = new ExpInitializer(dsym.loc, e);
 1311                 goto Ldtor;
 1312             }
 1313             if (tv.ty == Tstruct && (cast(TypeStruct)tv).sym.zeroInit)
 1314             {
 1315                 /* If a struct is all zeros, as a special case
 1316                  * set it's initializer to the integer 0.
 1317                  * In AssignExp::toElem(), we check for this and issue
 1318                  * a memset() to initialize the struct.
 1319                  * Must do same check in interpreter.
 1320                  */
 1321                 Expression e = IntegerExp.literal!0;
 1322                 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
 1323                 e.type = dsym.type;      // don't type check this, it would fail
 1324                 dsym._init = new ExpInitializer(dsym.loc, e);
 1325                 goto Ldtor;
 1326             }
 1327             if (dsym.type.baseElemOf().ty == Tvoid)
 1328             {
 1329                 dsym.error("`%s` does not have a default initializer", dsym.type.toChars());
 1330             }
 1331             else if (auto e = dsym.type.defaultInit(dsym.loc))
 1332             {
 1333                 dsym._init = new ExpInitializer(dsym.loc, e);
 1334             }
 1335 
 1336             // Default initializer is always a blit
 1337             isBlit = true;
 1338         }
 1339         if (dsym._init)
 1340         {
 1341             sc = sc.push();
 1342             sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);
 1343 
 1344             ExpInitializer ei = dsym._init.isExpInitializer();
 1345             if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424
 1346                     // Preset the required type to fail in FuncLiteralDeclaration::semantic3
 1347                 ei.exp = inferType(ei.exp, dsym.type);
 1348 
 1349             // If inside function, there is no semantic3() call
 1350             if (sc.func || sc.intypeof == 1)
 1351             {
 1352                 // If local variable, use AssignExp to handle all the various
 1353                 // possibilities.
 1354                 if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.tls | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())
 1355                 {
 1356                     //printf("fd = '%s', var = '%s'\n", fd.toChars(), toChars());
 1357                     if (!ei)
 1358                     {
 1359                         ArrayInitializer ai = dsym._init.isArrayInitializer();
 1360                         Expression e;
 1361                         if (ai && tb.ty == Taarray)
 1362                             e = ai.toAssocArrayLiteral();
 1363                         else
 1364                             e = dsym._init.initializerToExpression();
 1365                         if (!e)
 1366                         {
 1367                             // Run semantic, but don't need to interpret
 1368                             dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret);
 1369                             e = dsym._init.initializerToExpression();
 1370                             if (!e)
 1371                             {
 1372                                 dsym.error("is not a static and cannot have static initializer");
 1373                                 e = ErrorExp.get();
 1374                             }
 1375                         }
 1376                         ei = new ExpInitializer(dsym._init.loc, e);
 1377                         dsym._init = ei;
 1378                     }
 1379 
 1380                     Expression exp = ei.exp;
 1381                     Expression e1 = new VarExp(dsym.loc, dsym);
 1382                     if (isBlit)
 1383                         exp = new BlitExp(dsym.loc, e1, exp);
 1384                     else
 1385                         exp = new ConstructExp(dsym.loc, e1, exp);
 1386                     dsym.canassign++;
 1387                     exp = exp.expressionSemantic(sc);
 1388                     dsym.canassign--;
 1389                     exp = exp.optimize(WANTvalue);
 1390                     if (exp.op == TOK.error)
 1391                     {
 1392                         dsym._init = new ErrorInitializer();
 1393                         ei = null;
 1394                     }
 1395                     else
 1396                         ei.exp = exp;
 1397 
 1398                     if (ei && dsym.isScope())
 1399                     {
 1400                         Expression ex = ei.exp.lastComma();
 1401                         if (ex.op == TOK.blit || ex.op == TOK.construct)
 1402                             ex = (cast(AssignExp)ex).e2;
 1403                         if (ex.op == TOK.new_)
 1404                         {
 1405                             // See if initializer is a NewExp that can be allocated on the stack
 1406                             NewExp ne = cast(NewExp)ex;
 1407                             if (dsym.type.toBasetype().ty == Tclass)
 1408                             {
 1409                                 if (ne.newargs && ne.newargs.dim > 1)
 1410                                 {
 1411                                     dsym.mynew = true;
 1412                                 }
 1413                                 else
 1414                                 {
 1415                                     ne.onstack = 1;
 1416                                     dsym.onstack = true;
 1417                                 }
 1418                             }
 1419                         }
 1420                         else if (ex.op == TOK.function_)
 1421                         {
 1422                             // or a delegate that doesn't escape a reference to the function
 1423                             FuncDeclaration f = (cast(FuncExp)ex).fd;
 1424                             if (f.tookAddressOf)
 1425                                 f.tookAddressOf--;
 1426                         }
 1427                     }
 1428                 }
 1429                 else
 1430                 {
 1431                     // https://issues.dlang.org/show_bug.cgi?id=14166
 1432                     // Don't run CTFE for the temporary variables inside typeof
 1433                     dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);
 1434                     const init_err = dsym._init.isExpInitializer();
 1435                     if (init_err && init_err.exp.op == TOK.showCtfeContext)
 1436                     {
 1437                          errorSupplemental(dsym.loc, "compile time context created here");
 1438                     }
 1439                 }
 1440             }
 1441             else if (parent.isAggregateDeclaration())
 1442             {
 1443                 dsym._scope = scx ? scx : sc.copy();
 1444                 dsym._scope.setNoFree();
 1445             }
 1446             else if (dsym.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) || dsym.type.isConst() || dsym.type.isImmutable())
 1447             {
 1448                 /* Because we may need the results of a const declaration in a
 1449                  * subsequent type, such as an array dimension, before semantic2()
 1450                  * gets ordinarily run, try to run semantic2() now.
 1451                  * Ignore failure.
 1452                  */
 1453                 if (!inferred)
 1454                 {
 1455                     uint errors = global.errors;
 1456                     dsym.inuse++;
 1457                     // Bug 20549. Don't try this on modules or packages, syntaxCopy
 1458                     // could crash (inf. recursion) on a mod/pkg referencing itself
 1459                     if (ei && (ei.exp.op != TOK.scope_ ? true : !(cast(ScopeExp)ei.exp).sds.isPackage()))
 1460                     {
 1461                         Expression exp = ei.exp.syntaxCopy();
 1462 
 1463                         bool needctfe = dsym.isDataseg() || (dsym.storage_class & STC.manifest);
 1464                         if (needctfe)
 1465                             sc = sc.startCTFE();
 1466                         exp = exp.expressionSemantic(sc);
 1467                         exp = resolveProperties(sc, exp);
 1468                         if (needctfe)
 1469                             sc = sc.endCTFE();
 1470 
 1471                         Type tb2 = dsym.type.toBasetype();
 1472                         Type ti = exp.type.toBasetype();
 1473 
 1474                         /* The problem is the following code:
 1475                          *  struct CopyTest {
 1476                          *     double x;
 1477                          *     this(double a) { x = a * 10.0;}
 1478                          *     this(this) { x += 2.0; }
 1479                          *  }
 1480                          *  const CopyTest z = CopyTest(5.3);  // ok
 1481                          *  const CopyTest w = z;              // not ok, postblit not run
 1482                          *  static assert(w.x == 55.0);
 1483                          * because the postblit doesn't get run on the initialization of w.
 1484                          */
 1485                         if (auto ts = ti.isTypeStruct())
 1486                         {
 1487                             StructDeclaration sd = ts.sym;
 1488                             /* Look to see if initializer involves a copy constructor
 1489                              * (which implies a postblit)
 1490                              */
 1491                             // there is a copy constructor
 1492                             // and exp is the same struct
 1493                             if (sd.postblit && tb2.toDsymbol(null) == sd)
 1494                             {
 1495                                 // The only allowable initializer is a (non-copy) constructor
 1496                                 if (exp.isLvalue())
 1497                                     dsym.error("of type struct `%s` uses `this(this)`, which is not allowed in static initialization", tb2.toChars());
 1498                             }
 1499                         }
 1500                         ei.exp = exp;
 1501                     }
 1502                     dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
 1503                     dsym.inuse--;
 1504                     if (global.errors > errors)
 1505                     {
 1506                         dsym._init = new ErrorInitializer();
 1507                         dsym.type = Type.terror;
 1508                     }
 1509                 }
 1510                 else
 1511                 {
 1512                     dsym._scope = scx ? scx : sc.copy();
 1513                     dsym._scope.setNoFree();
 1514                 }
 1515             }
 1516             sc = sc.pop();
 1517         }
 1518 
 1519     Ldtor:
 1520         /* Build code to execute destruction, if necessary
 1521          */
 1522         dsym.edtor = dsym.callScopeDtor(sc);
 1523         if (dsym.edtor)
 1524         {
 1525             /* If dsym is a local variable, who's type is a struct with a scope destructor,
 1526              * then make dsym scope, too.
 1527              */
 1528             if (global.params.vsafe &&
 1529                 !(dsym.storage_class & (STC.parameter | STC.temp | STC.field | STC.in_ | STC.foreach_ | STC.result | STC.manifest)) &&
 1530                 !dsym.isDataseg() &&
 1531                 !dsym.doNotInferScope &&
 1532                 dsym.type.hasPointers())
 1533             {
 1534                 auto tv = dsym.type.baseElemOf();
 1535                 if (tv.ty == Tstruct &&
 1536                     (cast(TypeStruct)tv).sym.dtor.storage_class & STC.scope_)
 1537                 {
 1538                     dsym.storage_class |= STC.scope_;
 1539                 }
 1540             }
 1541 
 1542             if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared))
 1543                 dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope);
 1544             else
 1545                 dsym.edtor = dsym.edtor.expressionSemantic(sc);
 1546 
 1547             version (none)
 1548             {
 1549                 // currently disabled because of std.stdio.stdin, stdout and stderr
 1550                 if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_))
 1551                     dsym.error("static storage variables cannot have destructors");
 1552             }
 1553         }
 1554 
 1555         dsym.semanticRun = PASS.semanticdone;
 1556 
 1557         if (dsym.type.toBasetype().ty == Terror)
 1558             dsym.errors = true;
 1559 
 1560         if(sc.scopesym && !sc.scopesym.isAggregateDeclaration())
 1561         {
 1562             for (ScopeDsymbol sym = sc.scopesym; sym && dsym.endlinnum == 0;
 1563                  sym = sym.parent ? sym.parent.isScopeDsymbol() : null)
 1564                 dsym.endlinnum = sym.endlinnum;
 1565         }
 1566     }
 1567 
 1568     override void visit(TypeInfoDeclaration dsym)
 1569     {
 1570         assert(dsym.linkage == LINK.c);
 1571     }
 1572 
 1573     override void visit(Import imp)
 1574     {
 1575         //printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
 1576         if (imp.semanticRun > PASS.init)
 1577             return;
 1578 
 1579         if (imp._scope)
 1580         {
 1581             sc = imp._scope;
 1582             imp._scope = null;
 1583         }
 1584         if (!sc)
 1585             return;
 1586 
 1587         imp.semanticRun = PASS.semantic;
 1588 
 1589         // Load if not already done so
 1590         bool loadErrored = false;
 1591         if (!imp.mod)
 1592         {
 1593             loadErrored = imp.load(sc);
 1594             if (imp.mod)
 1595             {
 1596                 imp.mod.importAll(null);
 1597                 imp.mod.checkImportDeprecation(imp.loc, sc);
 1598             }
 1599         }
 1600         if (imp.mod)
 1601         {
 1602             // Modules need a list of each imported module
 1603 
 1604             // if inside a template instantiation, the instantianting
 1605             // module gets the import.
 1606             // https://issues.dlang.org/show_bug.cgi?id=17181
 1607             Module importer = sc._module;
 1608             if (sc.minst && sc.tinst)
 1609             {
 1610                 importer = sc.minst;
 1611                 if (!sc.tinst.importedModules.contains(imp.mod))
 1612                     sc.tinst.importedModules.push(imp.mod);
 1613             }
 1614             //printf("%s imports %s\n", importer.toChars(), imp.mod.toChars());
 1615             if (!importer.aimports.contains(imp.mod))
 1616                 importer.aimports.push(imp.mod);
 1617 
 1618             if (sc.explicitProtection)
 1619                 imp.protection = sc.protection;
 1620 
 1621             if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import
 1622             {
 1623                 ScopeDsymbol scopesym;
 1624                 for (Scope* scd = sc; scd; scd = scd.enclosing)
 1625                 {
 1626                     if (!scd.scopesym)
 1627                         continue;
 1628                     scopesym = scd.scopesym;
 1629                     break;
 1630                 }
 1631 
 1632                 if (!imp.isstatic)
 1633                 {
 1634                     scopesym.importScope(imp.mod, imp.protection);
 1635                 }
 1636 
 1637                 // Mark the imported packages as accessible from the current
 1638                 // scope. This access check is necessary when using FQN b/c
 1639                 // we're using a single global package tree.
 1640                 // https://issues.dlang.org/show_bug.cgi?id=313
 1641                 if (imp.packages)
 1642                 {
 1643                     // import a.b.c.d;
 1644                     auto p = imp.pkg; // a
 1645                     scopesym.addAccessiblePackage(p, imp.protection);
 1646                     foreach (id; (*imp.packages)[1 .. imp.packages.dim]) // [b, c]
 1647                     {
 1648                         p = cast(Package) p.symtab.lookup(id);
 1649                         // https://issues.dlang.org/show_bug.cgi?id=17991
 1650                         // An import of truly empty file/package can happen
 1651                         // https://issues.dlang.org/show_bug.cgi?id=20151
 1652                         // Package in the path conflicts with a module name
 1653                         if (p is null)
 1654                             break;
 1655                         scopesym.addAccessiblePackage(p, imp.protection);
 1656                     }
 1657                 }
 1658                 scopesym.addAccessiblePackage(imp.mod, imp.protection); // d
 1659             }
 1660 
 1661             if (!loadErrored)
 1662             {
 1663                 imp.mod.dsymbolSemantic(null);
 1664             }
 1665 
 1666             if (imp.mod.needmoduleinfo)
 1667             {
 1668                 //printf("module4 %s because of %s\n", importer.toChars(), imp.mod.toChars());
 1669                 importer.needmoduleinfo = 1;
 1670             }
 1671 
 1672             sc = sc.push(imp.mod);
 1673             sc.protection = imp.protection;
 1674             for (size_t i = 0; i < imp.aliasdecls.dim; i++)
 1675             {
 1676                 AliasDeclaration ad = imp.aliasdecls[i];
 1677                 //printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
 1678                 Dsymbol sym = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);
 1679                 if (sym)
 1680                 {
 1681                     import dmd.access : symbolIsVisible;
 1682                     if (!symbolIsVisible(sc, sym))
 1683                         imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`",
 1684                             imp.names[i].toChars(), sc._module.toChars());
 1685                     ad.dsymbolSemantic(sc);
 1686                     // If the import declaration is in non-root module,
 1687                     // analysis of the aliased symbol is deferred.
 1688                     // Therefore, don't see the ad.aliassym or ad.type here.
 1689                 }
 1690                 else
 1691                 {
 1692                     Dsymbol s = imp.mod.search_correct(imp.names[i]);
 1693                     if (s)
 1694                         imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
 1695                     else
 1696                         imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
 1697                     ad.type = Type.terror;
 1698                 }
 1699             }
 1700             sc = sc.pop();
 1701         }
 1702 
 1703         imp.semanticRun = PASS.semanticdone;
 1704 
 1705         // object self-imports itself, so skip that
 1706         // https://issues.dlang.org/show_bug.cgi?id=7547
 1707         // don't list pseudo modules __entrypoint.d, __main.d
 1708         // https://issues.dlang.org/show_bug.cgi?id=11117
 1709         // https://issues.dlang.org/show_bug.cgi?id=11164
 1710         if (global.params.moduleDeps !is null && !(imp.id == Id.object && sc._module.ident == Id.object) &&
 1711             strcmp(sc._module.ident.toChars(), "__main") != 0)
 1712         {
 1713             /* The grammar of the file is:
 1714              *      ImportDeclaration
 1715              *          ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
 1716              *      ModuleAliasIdentifier ] "\n"
 1717              *
 1718              *      BasicImportDeclaration
 1719              *          ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
 1720              *              " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
 1721              *
 1722              *      FilePath
 1723              *          - any string with '(', ')' and '\' escaped with the '\' character
 1724              */
 1725             OutBuffer* ob = global.params.moduleDeps;
 1726             Module imod = sc.instantiatingModule();
 1727             if (!global.params.moduleDepsFile)
 1728                 ob.writestring("depsImport ");
 1729             ob.writestring(imod.toPrettyChars());
 1730             ob.writestring(" (");
 1731             escapePath(ob, imod.srcfile.toChars());
 1732             ob.writestring(") : ");
 1733             // use protection instead of sc.protection because it couldn't be
 1734             // resolved yet, see the comment above
 1735             protectionToBuffer(ob, imp.protection);
 1736             ob.writeByte(' ');
 1737             if (imp.isstatic)
 1738             {
 1739                 stcToBuffer(ob, STC.static_);
 1740                 ob.writeByte(' ');
 1741             }
 1742             ob.writestring(": ");
 1743             if (imp.packages)
 1744             {
 1745                 for (size_t i = 0; i < imp.packages.dim; i++)
 1746                 {
 1747                     Identifier pid = (*imp.packages)[i];
 1748                     ob.printf("%s.", pid.toChars());
 1749                 }
 1750             }
 1751             ob.writestring(imp.id.toString());
 1752             ob.writestring(" (");
 1753             if (imp.mod)
 1754                 escapePath(ob, imp.mod.srcfile.toChars());
 1755             else
 1756                 ob.writestring("???");
 1757             ob.writeByte(')');
 1758             foreach (i, name; imp.names)
 1759             {
 1760                 if (i == 0)
 1761                     ob.writeByte(':');
 1762                 else
 1763                     ob.writeByte(',');
 1764                 Identifier _alias = imp.aliases[i];
 1765                 if (!_alias)
 1766                 {
 1767                     ob.printf("%s", name.toChars());
 1768                     _alias = name;
 1769                 }
 1770                 else
 1771                     ob.printf("%s=%s", _alias.toChars(), name.toChars());
 1772             }
 1773             if (imp.aliasId)
 1774                 ob.printf(" -> %s", imp.aliasId.toChars());
 1775             ob.writenl();
 1776         }
 1777         //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
 1778     }
 1779 
 1780     void attribSemantic(AttribDeclaration ad)
 1781     {
 1782         if (ad.semanticRun != PASS.init)
 1783             return;
 1784         ad.semanticRun = PASS.semantic;
 1785         Dsymbols* d = ad.include(sc);
 1786         //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
 1787         if (d)
 1788         {
 1789             Scope* sc2 = ad.newScope(sc);
 1790             bool errors;
 1791             for (size_t i = 0; i < d.dim; i++)
 1792             {
 1793                 Dsymbol s = (*d)[i];
 1794                 s.dsymbolSemantic(sc2);
 1795                 errors |= s.errors;
 1796             }
 1797             ad.errors |= errors;
 1798             if (sc2 != sc)
 1799                 sc2.pop();
 1800         }
 1801         ad.semanticRun = PASS.semanticdone;
 1802     }
 1803 
 1804     override void visit(AttribDeclaration atd)
 1805     {
 1806         attribSemantic(atd);
 1807     }
 1808 
 1809     override void visit(AnonDeclaration scd)
 1810     {
 1811         //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
 1812         assert(sc.parent);
 1813         auto p = sc.parent.pastMixin();
 1814         auto ad = p.isAggregateDeclaration();
 1815         if (!ad)
 1816         {
 1817             error(scd.loc, "%s can only be a part of an aggregate, not %s `%s`", scd.kind(), p.kind(), p.toChars());
 1818             scd.errors = true;
 1819             return;
 1820         }
 1821 
 1822         if (scd.decl)
 1823         {
 1824             sc = sc.push();
 1825             sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.gshared);
 1826             sc.inunion = scd.isunion ? scd : null;
 1827             sc.flags = 0;
 1828             for (size_t i = 0; i < scd.decl.dim; i++)
 1829             {
 1830                 Dsymbol s = (*scd.decl)[i];
 1831                 s.dsymbolSemantic(sc);
 1832             }
 1833             sc = sc.pop();
 1834         }
 1835     }
 1836 
 1837     override void visit(PragmaDeclaration pd)
 1838     {
 1839         // Should be merged with PragmaStatement
 1840         //printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
 1841         if (global.params.mscoff)
 1842         {
 1843             if (pd.ident == Id.linkerDirective)
 1844             {
 1845                 if (!pd.args || pd.args.dim != 1)
 1846                     pd.error("one string argument expected for pragma(linkerDirective)");
 1847                 else
 1848                 {
 1849                     auto se = semanticString(sc, (*pd.args)[0], "linker directive");
 1850                     if (!se)
 1851                         goto Lnodecl;
 1852                     (*pd.args)[0] = se;
 1853                     if (global.params.verbose)
 1854                         message("linkopt   %.*s", cast(int)se.len, se.peekString().ptr);
 1855                 }
 1856                 goto Lnodecl;
 1857             }
 1858         }
 1859         if (pd.ident == Id.msg)
 1860         {
 1861             if (pd.args)
 1862             {
 1863                 for (size_t i = 0; i < pd.args.dim; i++)
 1864                 {
 1865                     Expression e = (*pd.args)[i];
 1866                     sc = sc.startCTFE();
 1867                     e = e.expressionSemantic(sc);
 1868                     e = resolveProperties(sc, e);
 1869                     sc = sc.endCTFE();
 1870                     // pragma(msg) is allowed to contain types as well as expressions
 1871                     if (e.type && e.type.ty == Tvoid)
 1872                     {
 1873                         error(pd.loc, "Cannot pass argument `%s` to `pragma msg` because it is `void`", e.toChars());
 1874                         return;
 1875                     }
 1876                     e = ctfeInterpretForPragmaMsg(e);
 1877                     if (e.op == TOK.error)
 1878                     {
 1879                         errorSupplemental(pd.loc, "while evaluating `pragma(msg, %s)`", (*pd.args)[i].toChars());
 1880                         return;
 1881                     }
 1882                     StringExp se = e.toStringExp();
 1883                     if (se)
 1884                     {
 1885                         se = se.toUTF8(sc);
 1886                         fprintf(stderr, "%.*s", cast(int)se.len, se.peekString().ptr);
 1887                     }
 1888                     else
 1889                         fprintf(stderr, "%s", e.toChars());
 1890                 }
 1891                 fprintf(stderr, "\n");
 1892             }
 1893             goto Lnodecl;
 1894         }
 1895         else if (pd.ident == Id.lib)
 1896         {
 1897             if (!pd.args || pd.args.dim != 1)
 1898                 pd.error("string expected for library name");
 1899             else
 1900             {
 1901                 auto se = semanticString(sc, (*pd.args)[0], "library name");
 1902                 if (!se)
 1903                     goto Lnodecl;
 1904                 (*pd.args)[0] = se;
 1905 
 1906                 auto name = se.peekString().xarraydup;
 1907                 if (global.params.verbose)
 1908                     message("library   %s", name.ptr);
 1909                 if (global.params.moduleDeps && !global.params.moduleDepsFile)
 1910                 {
 1911                     OutBuffer* ob = global.params.moduleDeps;
 1912                     Module imod = sc.instantiatingModule();
 1913                     ob.writestring("depsLib ");
 1914                     ob.writestring(imod.toPrettyChars());
 1915                     ob.writestring(" (");
 1916                     escapePath(ob, imod.srcfile.toChars());
 1917                     ob.writestring(") : ");
 1918                     ob.writestring(name);
 1919                     ob.writenl();
 1920                 }
 1921                 mem.xfree(name.ptr);
 1922             }
 1923             goto Lnodecl;
 1924         }
 1925         else if (pd.ident == Id.startaddress)
 1926         {
 1927             if (!pd.args || pd.args.dim != 1)
 1928                 pd.error("function name expected for start address");
 1929             else
 1930             {
 1931                 /* https://issues.dlang.org/show_bug.cgi?id=11980
 1932                  * resolveProperties and ctfeInterpret call are not necessary.
 1933                  */
 1934                 Expression e = (*pd.args)[0];
 1935                 sc = sc.startCTFE();
 1936                 e = e.expressionSemantic(sc);
 1937                 sc = sc.endCTFE();
 1938                 (*pd.args)[0] = e;
 1939                 Dsymbol sa = getDsymbol(e);
 1940                 if (!sa || !sa.isFuncDeclaration())
 1941                     pd.error("function name expected for start address, not `%s`", e.toChars());
 1942             }
 1943             goto Lnodecl;
 1944         }
 1945         else if (pd.ident == Id.Pinline)
 1946         {
 1947             goto Ldecl;
 1948         }
 1949         else if (pd.ident == Id.mangle)
 1950         {
 1951             if (!pd.args)
 1952                 pd.args = new Expressions();
 1953             if (pd.args.dim != 1)
 1954             {
 1955                 pd.error("string expected for mangled name");
 1956                 pd.args.setDim(1);
 1957                 (*pd.args)[0] = ErrorExp.get(); // error recovery
 1958                 goto Ldecl;
 1959             }
 1960 
 1961             auto se = semanticString(sc, (*pd.args)[0], "mangled name");
 1962             if (!se)
 1963                 goto Ldecl;
 1964             (*pd.args)[0] = se; // Will be used later
 1965 
 1966             if (!se.len)
 1967             {
 1968                 pd.error("zero-length string not allowed for mangled name");
 1969                 goto Ldecl;
 1970             }
 1971             if (se.sz != 1)
 1972             {
 1973                 pd.error("mangled name characters can only be of type `char`");
 1974                 goto Ldecl;
 1975             }
 1976             version (all)
 1977             {
 1978                 /* Note: D language specification should not have any assumption about backend
 1979                  * implementation. Ideally pragma(mangle) can accept a string of any content.
 1980                  *
 1981                  * Therefore, this validation is compiler implementation specific.
 1982                  */
 1983                 auto slice = se.peekString();
 1984                 for (size_t i = 0; i < se.len;)
 1985                 {
 1986                     dchar c = slice[i];
 1987                     if (c < 0x80)
 1988                     {
 1989                         if (c.isValidMangling)
 1990                         {
 1991                             ++i;
 1992                             continue;
 1993                         }
 1994                         else
 1995                         {
 1996                             pd.error("char 0x%02x not allowed in mangled name", c);
 1997                             break;
 1998                         }
 1999                     }
 2000                     if (const msg = utf_decodeChar(slice, i, c))
 2001                     {
 2002                         pd.error("%.*s", cast(int)msg.length, msg.ptr);
 2003                         break;
 2004                     }
 2005                     if (!isUniAlpha(c))
 2006                     {
 2007                         pd.error("char `0x%04x` not allowed in mangled name", c);
 2008                         break;
 2009                     }
 2010                 }
 2011             }
 2012         }
 2013         else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
 2014         {
 2015             if (pd.args && pd.args.dim != 0)
 2016                 pd.error("takes no argument");
 2017             goto Ldecl;
 2018         }
 2019         else if (pd.ident == Id.printf || pd.ident == Id.scanf)
 2020         {
 2021             if (pd.args && pd.args.dim != 0)
 2022                 pd.error("takes no argument");
 2023             goto Ldecl;
 2024         }
 2025         else if (global.params.ignoreUnsupportedPragmas)
 2026         {
 2027             if (global.params.verbose)
 2028             {
 2029                 /* Print unrecognized pragmas
 2030                  */
 2031                 OutBuffer buf;
 2032                 buf.writestring(pd.ident.toString());
 2033                 if (pd.args)
 2034                 {
 2035                     const errors_save = global.startGagging();
 2036                     for (size_t i = 0; i < pd.args.dim; i++)
 2037                     {
 2038                         Expression e = (*pd.args)[i];
 2039                         sc = sc.startCTFE();
 2040                         e = e.expressionSemantic(sc);
 2041                         e = resolveProperties(sc, e);
 2042                         sc = sc.endCTFE();
 2043                         e = e.ctfeInterpret();
 2044                         if (i == 0)
 2045                             buf.writestring(" (");
 2046                         else
 2047                             buf.writeByte(',');
 2048                         buf.writestring(e.toChars());
 2049                     }
 2050                     if (pd.args.dim)
 2051                         buf.writeByte(')');
 2052                     global.endGagging(errors_save);
 2053                 }
 2054                 message("pragma    %s", buf.peekChars());
 2055             }
 2056         }
 2057         else
 2058             error(pd.loc, "unrecognized `pragma(%s)`", pd.ident.toChars());
 2059     Ldecl:
 2060         if (pd.decl)
 2061         {
 2062             Scope* sc2 = pd.newScope(sc);
 2063             for (size_t i = 0; i < pd.decl.dim; i++)
 2064             {
 2065                 Dsymbol s = (*pd.decl)[i];
 2066                 s.dsymbolSemantic(sc2);
 2067                 if (pd.ident == Id.mangle)
 2068                 {
 2069                     assert(pd.args && pd.args.dim == 1);
 2070                     if (auto se = (*pd.args)[0].toStringExp())
 2071                     {
 2072                         const name = (cast(const(char)[])se.peekData()).xarraydup;
 2073                         uint cnt = setMangleOverride(s, name);
 2074                         if (cnt > 1)
 2075                             pd.error("can only apply to a single declaration");
 2076                     }
 2077                 }
 2078             }
 2079             if (sc2 != sc)
 2080                 sc2.pop();
 2081         }
 2082         return;
 2083     Lnodecl:
 2084         if (pd.decl)
 2085         {
 2086             pd.error("is missing a terminating `;`");
 2087             goto Ldecl;
 2088             // do them anyway, to avoid segfaults.
 2089         }
 2090     }
 2091 
 2092     override void visit(StaticIfDeclaration sid)
 2093     {
 2094         attribSemantic(sid);
 2095     }
 2096 
 2097     override void visit(StaticForeachDeclaration sfd)
 2098     {
 2099         attribSemantic(sfd);
 2100     }
 2101 
 2102     private Dsymbols* compileIt(CompileDeclaration cd)
 2103     {
 2104         //printf("CompileDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars());
 2105         OutBuffer buf;
 2106         if (expressionsToString(buf, sc, cd.exps))
 2107             return null;
 2108 
 2109         const errors = global.errors;
 2110         const len = buf.length;
 2111         buf.writeByte(0);
 2112         const str = buf.extractSlice()[0 .. len];
 2113         scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false);
 2114         p.nextToken();
 2115 
 2116         auto d = p.parseDeclDefs(0);
 2117         if (global.errors != errors)
 2118             return null;
 2119 
 2120         if (p.token.value != TOK.endOfFile)
 2121         {
 2122             cd.error("incomplete mixin declaration `%s`", str.ptr);
 2123             return null;
 2124         }
 2125         return d;
 2126     }
 2127 
 2128     /***********************************************************
 2129      * https://dlang.org/spec/module.html#mixin-declaration
 2130      */
 2131     override void visit(CompileDeclaration cd)
 2132     {
 2133         //printf("CompileDeclaration::semantic()\n");
 2134         if (!cd.compiled)
 2135         {
 2136             cd.decl = compileIt(cd);
 2137             cd.AttribDeclaration.addMember(sc, cd.scopesym);
 2138             cd.compiled = true;
 2139 
 2140             if (cd._scope && cd.decl)
 2141             {
 2142                 for (size_t i = 0; i < cd.decl.dim; i++)
 2143                 {
 2144                     Dsymbol s = (*cd.decl)[i];
 2145                     s.setScope(cd._scope);
 2146                 }
 2147             }
 2148         }
 2149         attribSemantic(cd);
 2150     }
 2151 
 2152     override void visit(CPPNamespaceDeclaration ns)
 2153     {
 2154         Identifier identFromSE (StringExp se)
 2155         {
 2156             const sident = se.toStringz();
 2157             if (!sident.length || !Identifier.isValidIdentifier(sident))
 2158             {
 2159                 ns.exp.error("expected valid identifer for C++ namespace but got `%.*s`",
 2160                              cast(int)sident.length, sident.ptr);
 2161                 return null;
 2162             }
 2163             else
 2164                 return Identifier.idPool(sident);
 2165         }
 2166 
 2167         if (ns.ident is null)
 2168         {
 2169             ns.cppnamespace = sc.namespace;
 2170             sc = sc.startCTFE();
 2171             ns.exp = ns.exp.expressionSemantic(sc);
 2172             ns.exp = resolveProperties(sc, ns.exp);
 2173             sc = sc.endCTFE();
 2174             ns.exp = ns.exp.ctfeInterpret();
 2175             // Can be either a tuple of strings or a string itself
 2176             if (auto te = ns.exp.isTupleExp())
 2177             {
 2178                 expandTuples(te.exps);
 2179                 CPPNamespaceDeclaration current = ns.cppnamespace;
 2180                 for (size_t d = 0; d < te.exps.dim; ++d)
 2181                 {
 2182                     auto exp = (*te.exps)[d];
 2183                     auto prev = d ? current : ns.cppnamespace;
 2184                     current = (d + 1) != te.exps.dim
 2185                         ? new CPPNamespaceDeclaration(exp, null)
 2186                         : ns;
 2187                     current.exp = exp;
 2188                     current.cppnamespace = prev;
 2189                     if (auto se = exp.toStringExp())
 2190                     {
 2191                         current.ident = identFromSE(se);
 2192                         if (current.ident is null)
 2193                             return; // An error happened in `identFromSE`
 2194                     }
 2195                     else
 2196                         ns.exp.error("`%s`: index %llu is not a string constant, it is a `%s`",
 2197                                      ns.exp.toChars(), cast(ulong) d, ns.exp.type.toChars());
 2198                 }
 2199             }
 2200             else if (auto se = ns.exp.toStringExp())
 2201                 ns.ident = identFromSE(se);
 2202             else
 2203                 ns.exp.error("compile time string constant (or tuple) expected, not `%s`",
 2204                              ns.exp.toChars());
 2205         }
 2206         if (ns.ident)
 2207             attribSemantic(ns);
 2208     }
 2209 
 2210     override void visit(UserAttributeDeclaration uad)
 2211     {
 2212         //printf("UserAttributeDeclaration::semantic() %p\n", this);
 2213         if (uad.decl && !uad._scope)
 2214             uad.Dsymbol.setScope(sc); // for function local symbols
 2215         arrayExpressionSemantic(uad.atts, sc, true);
 2216         return attribSemantic(uad);
 2217     }
 2218 
 2219     override void visit(StaticAssert sa)
 2220     {
 2221         if (sa.semanticRun < PASS.semanticdone)
 2222             sa.semanticRun = PASS.semanticdone;
 2223     }
 2224 
 2225     override void visit(DebugSymbol ds)
 2226     {
 2227         //printf("DebugSymbol::semantic() %s\n", toChars());
 2228         if (ds.semanticRun < PASS.semanticdone)
 2229             ds.semanticRun = PASS.semanticdone;
 2230     }
 2231 
 2232     override void visit(VersionSymbol vs)
 2233     {
 2234         if (vs.semanticRun < PASS.semanticdone)
 2235             vs.semanticRun = PASS.semanticdone;
 2236     }
 2237 
 2238     override void visit(Package pkg)
 2239     {
 2240         if (pkg.semanticRun < PASS.semanticdone)
 2241             pkg.semanticRun = PASS.semanticdone;
 2242     }
 2243 
 2244     override void visit(Module m)
 2245     {
 2246         if (m.semanticRun != PASS.init)
 2247             return;
 2248         //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
 2249         m.semanticRun = PASS.semantic;
 2250         // Note that modules get their own scope, from scratch.
 2251         // This is so regardless of where in the syntax a module
 2252         // gets imported, it is unaffected by context.
 2253         Scope* sc = m._scope; // see if already got one from importAll()
 2254         if (!sc)
 2255         {
 2256             Scope.createGlobal(m); // create root scope
 2257         }
 2258 
 2259         //printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
 2260         // Pass 1 semantic routines: do public side of the definition
 2261         m.members.foreachDsymbol( (s)
 2262         {
 2263             //printf("\tModule('%s'): '%s'.dsymbolSemantic()\n", toChars(), s.toChars());
 2264             s.dsymbolSemantic(sc);
 2265             m.runDeferredSemantic();
 2266         });
 2267 
 2268         if (m.userAttribDecl)
 2269         {
 2270             m.userAttribDecl.dsymbolSemantic(sc);
 2271         }
 2272         if (!m._scope)
 2273         {
 2274             sc = sc.pop();
 2275             sc.pop(); // 2 pops because Scope::createGlobal() created 2
 2276         }
 2277         m.semanticRun = PASS.semanticdone;
 2278         //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
 2279     }
 2280 
 2281     override void visit(EnumDeclaration ed)
 2282     {
 2283         //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), toChars());
 2284         //printf("EnumDeclaration::semantic() %p %s\n", this, toChars());
 2285         if (ed.semanticRun >= PASS.semanticdone)
 2286             return; // semantic() already completed
 2287         if (ed.semanticRun == PASS.semantic)
 2288         {
 2289             assert(ed.memtype);
 2290             error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
 2291             ed.errors = true;
 2292             ed.semanticRun = PASS.semanticdone;
 2293             return;
 2294         }
 2295         uint dprogress_save = Module.dprogress;
 2296 
 2297         Scope* scx = null;
 2298         if (ed._scope)
 2299         {
 2300             sc = ed._scope;
 2301             scx = ed._scope; // save so we don't make redundant copies
 2302             ed._scope = null;
 2303         }
 2304 
 2305         if (!sc)
 2306             return;
 2307 
 2308         ed.parent = sc.parent;
 2309         ed.type = ed.type.typeSemantic(ed.loc, sc);
 2310 
 2311         ed.protection = sc.protection;
 2312         if (sc.stc & STC.deprecated_)
 2313             ed.isdeprecated = true;
 2314         ed.userAttribDecl = sc.userAttribDecl;
 2315         ed.cppnamespace = sc.namespace;
 2316 
 2317         ed.semanticRun = PASS.semantic;
 2318         UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
 2319 
 2320         if (!ed.members && !ed.memtype) // enum ident;
 2321         {
 2322             ed.semanticRun = PASS.semanticdone;
 2323             return;
 2324         }
 2325 
 2326         if (!ed.symtab)
 2327             ed.symtab = new DsymbolTable();
 2328 
 2329         /* The separate, and distinct, cases are:
 2330          *  1. enum { ... }
 2331          *  2. enum : memtype { ... }
 2332          *  3. enum ident { ... }
 2333          *  4. enum ident : memtype { ... }
 2334          *  5. enum ident : memtype;
 2335          *  6. enum ident;
 2336          */
 2337 
 2338         if (ed.memtype)
 2339         {
 2340             ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
 2341 
 2342             /* Check to see if memtype is forward referenced
 2343              */
 2344             if (auto te = ed.memtype.isTypeEnum())
 2345             {
 2346                 EnumDeclaration sym = cast(EnumDeclaration)te.toDsymbol(sc);
 2347                 if (!sym.memtype || !sym.members || !sym.symtab || sym._scope)
 2348                 {
 2349                     // memtype is forward referenced, so try again later
 2350                     deferDsymbolSemantic(ed, scx);
 2351                     Module.dprogress = dprogress_save;
 2352                     //printf("\tdeferring %s\n", toChars());
 2353                     ed.semanticRun = PASS.init;
 2354                     return;
 2355                 }
 2356             }
 2357             if (ed.memtype.ty == Tvoid)
 2358             {
 2359                 ed.error("base type must not be `void`");
 2360                 ed.memtype = Type.terror;
 2361             }
 2362             if (ed.memtype.ty == Terror)
 2363             {
 2364                 ed.errors = true;
 2365                 // poison all the members
 2366                 ed.members.foreachDsymbol( (s) { s.errors = true; } );
 2367                 ed.semanticRun = PASS.semanticdone;
 2368                 return;
 2369             }
 2370         }
 2371 
 2372         ed.semanticRun = PASS.semanticdone;
 2373 
 2374         if (!ed.members) // enum ident : memtype;
 2375             return;
 2376 
 2377         if (ed.members.dim == 0)
 2378         {
 2379             ed.error("enum `%s` must have at least one member", ed.toChars());
 2380             ed.errors = true;
 2381             return;
 2382         }
 2383 
 2384         Module.dprogress++;
 2385 
 2386         Scope* sce;
 2387         if (ed.isAnonymous())
 2388             sce = sc;
 2389         else
 2390         {
 2391             sce = sc.push(ed);
 2392             sce.parent = ed;
 2393         }
 2394         sce = sce.startCTFE();
 2395         sce.setNoFree(); // needed for getMaxMinValue()
 2396 
 2397         /* Each enum member gets the sce scope
 2398          */
 2399         ed.members.foreachDsymbol( (s)
 2400         {
 2401             EnumMember em = s.isEnumMember();
 2402             if (em)
 2403                 em._scope = sce;
 2404         });
 2405 
 2406         if (!ed.added)
 2407         {
 2408             /* addMember() is not called when the EnumDeclaration appears as a function statement,
 2409              * so we have to do what addMember() does and install the enum members in the right symbol
 2410              * table
 2411              */
 2412             ScopeDsymbol scopesym = null;
 2413             if (ed.isAnonymous())
 2414             {
 2415                 /* Anonymous enum members get added to enclosing scope.
 2416                  */
 2417                 for (Scope* sct = sce; 1; sct = sct.enclosing)
 2418                 {
 2419                     assert(sct);
 2420                     if (sct.scopesym)
 2421                     {
 2422                         scopesym = sct.scopesym;
 2423                         if (!sct.scopesym.symtab)
 2424                             sct.scopesym.symtab = new DsymbolTable();
 2425                         break;
 2426                     }
 2427                 }
 2428             }
 2429             else
 2430             {
 2431                 // Otherwise enum members are in the EnumDeclaration's symbol table
 2432                 scopesym = ed;
 2433             }
 2434 
 2435             ed.members.foreachDsymbol( (s)
 2436             {
 2437                 EnumMember em = s.isEnumMember();
 2438                 if (em)
 2439                 {
 2440                     em.ed = ed;
 2441                     em.addMember(sc, scopesym);
 2442                 }
 2443             });
 2444         }
 2445 
 2446         ed.members.foreachDsymbol( (s)
 2447         {
 2448             EnumMember em = s.isEnumMember();
 2449             if (em)
 2450                 em.dsymbolSemantic(em._scope);
 2451         });
 2452         //printf("defaultval = %lld\n", defaultval);
 2453 
 2454         //if (defaultval) printf("defaultval: %s %s\n", defaultval.toChars(), defaultval.type.toChars());
 2455         //printf("members = %s\n", members.toChars());
 2456     }
 2457 
 2458     override void visit(EnumMember em)
 2459     {
 2460         //printf("EnumMember::semantic() %s\n", toChars());
 2461 
 2462         void errorReturn()
 2463         {
 2464             em.errors = true;
 2465             em.semanticRun = PASS.semanticdone;
 2466         }
 2467 
 2468         if (em.errors || em.semanticRun >= PASS.semanticdone)
 2469             return;
 2470         if (em.semanticRun == PASS.semantic)
 2471         {
 2472             em.error("circular reference to `enum` member");
 2473             return errorReturn();
 2474         }
 2475         assert(em.ed);
 2476 
 2477         em.ed.dsymbolSemantic(sc);
 2478         if (em.ed.errors)
 2479             return errorReturn();
 2480         if (em.errors || em.semanticRun >= PASS.semanticdone)
 2481             return;
 2482 
 2483         if (em._scope)
 2484             sc = em._scope;
 2485         if (!sc)
 2486             return;
 2487 
 2488         em.semanticRun = PASS.semantic;
 2489 
 2490         em.protection = em.ed.isAnonymous() ? em.ed.protection : Prot(Prot.Kind.public_);
 2491         em.linkage = LINK.d;
 2492         em.storage_class |= STC.manifest;
 2493 
 2494         // https://issues.dlang.org/show_bug.cgi?id=9701
 2495         if (em.ed.isAnonymous())
 2496         {
 2497             if (em.userAttribDecl)
 2498                 em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
 2499             else
 2500                 em.userAttribDecl = em.ed.userAttribDecl;
 2501         }
 2502 
 2503         // Eval UDA in this same scope. Issues 19344, 20835, 21122
 2504         if (em.userAttribDecl)
 2505             em.userAttribDecl.setScope(sc);
 2506 
 2507         // The first enum member is special
 2508         bool first = (em == (*em.ed.members)[0]);
 2509 
 2510         if (em.origType)
 2511         {
 2512             em.origType = em.origType.typeSemantic(em.loc, sc);
 2513             em.type = em.origType;
 2514             assert(em.value); // "type id;" is not a valid enum member declaration
 2515         }
 2516 
 2517         if (em.value)
 2518         {
 2519             Expression e = em.value;
 2520             assert(e.dyncast() == DYNCAST.expression);
 2521             e = e.expressionSemantic(sc);
 2522             e = resolveProperties(sc, e);
 2523             e = e.ctfeInterpret();
 2524             if (e.op == TOK.error)
 2525                 return errorReturn();
 2526             if (first && !em.ed.memtype && !em.ed.isAnonymous())
 2527             {
 2528                 em.ed.memtype = e.type;
 2529                 if (em.ed.memtype.ty == Terror)
 2530                 {
 2531                     em.ed.errors = true;
 2532                     return errorReturn();
 2533                 }
 2534                 if (em.ed.memtype.ty != Terror)
 2535                 {
 2536                     /* https://issues.dlang.org/show_bug.cgi?id=11746
 2537                      * All of named enum members should have same type
 2538                      * with the first member. If the following members were referenced
 2539                      * during the first member semantic, their types should be unified.
 2540                      */
 2541                     em.ed.members.foreachDsymbol( (s)
 2542                     {
 2543                         EnumMember enm = s.isEnumMember();
 2544                         if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
 2545                             return;
 2546 
 2547                         //printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
 2548                         Expression ev = enm.value;
 2549                         ev = ev.implicitCastTo(sc, em.ed.memtype);
 2550                         ev = ev.ctfeInterpret();
 2551                         ev = ev.castTo(sc, em.ed.type);
 2552                         if (ev.op == TOK.error)
 2553                             em.ed.errors = true;
 2554                         enm.value = ev;
 2555                     });
 2556 
 2557                     if (em.ed.errors)
 2558                     {
 2559                         em.ed.memtype = Type.terror;
 2560                         return errorReturn();
 2561                     }
 2562                 }
 2563             }
 2564 
 2565             if (em.ed.memtype && !em.origType)
 2566             {
 2567                 e = e.implicitCastTo(sc, em.ed.memtype);
 2568                 e = e.ctfeInterpret();
 2569 
 2570                 // save origValue for better json output
 2571                 em.origValue = e;
 2572 
 2573                 if (!em.ed.isAnonymous())
 2574                 {
 2575                     e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
 2576                     e = e.ctfeInterpret();
 2577                 }
 2578             }
 2579             else if (em.origType)
 2580             {
 2581                 e = e.implicitCastTo(sc, em.origType);
 2582                 e = e.ctfeInterpret();
 2583                 assert(em.ed.isAnonymous());
 2584 
 2585                 // save origValue for better json output
 2586                 em.origValue = e;
 2587             }
 2588             em.value = e;
 2589         }
 2590         else if (first)
 2591         {
 2592             Type t;
 2593             if (em.ed.memtype)
 2594                 t = em.ed.memtype;
 2595             else
 2596             {
 2597                 t = Type.tint32;
 2598                 if (!em.ed.isAnonymous())
 2599                     em.ed.memtype = t;
 2600             }
 2601             Expression e = new IntegerExp(em.loc, 0, t);
 2602             e = e.ctfeInterpret();
 2603 
 2604             // save origValue for better json output
 2605             em.origValue = e;
 2606 
 2607             if (!em.ed.isAnonymous())
 2608             {
 2609                 e = e.castTo(sc, em.ed.type);
 2610                 e = e.ctfeInterpret();
 2611             }
 2612             em.value = e;
 2613         }
 2614         else
 2615         {
 2616             /* Find the previous enum member,
 2617              * and set this to be the previous value + 1
 2618              */
 2619             EnumMember emprev = null;
 2620             em.ed.members.foreachDsymbol( (s)
 2621             {
 2622                 if (auto enm = s.isEnumMember())
 2623                 {
 2624                     if (enm == em)
 2625                         return 1;       // found
 2626                     emprev = enm;
 2627                 }
 2628                 return 0;       // continue
 2629             });
 2630 
 2631             assert(emprev);
 2632             if (emprev.semanticRun < PASS.semanticdone) // if forward reference
 2633                 emprev.dsymbolSemantic(emprev._scope); // resolve it
 2634             if (emprev.errors)
 2635                 return errorReturn();
 2636 
 2637             Expression eprev = emprev.value;
 2638             // .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
 2639             Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
 2640                 ? em.ed.memtype
 2641                 : eprev.type;
 2642 
 2643             Expression emax = tprev.getProperty(sc, em.ed.loc, Id.max, 0);
 2644             emax = emax.expressionSemantic(sc);
 2645             emax = emax.ctfeInterpret();
 2646 
 2647             // Set value to (eprev + 1).
 2648             // But first check that (eprev != emax)
 2649             assert(eprev);
 2650             Expression e = new EqualExp(TOK.equal, em.loc, eprev, emax);
 2651             e = e.expressionSemantic(sc);
 2652             e = e.ctfeInterpret();
 2653             if (e.toInteger())
 2654             {
 2655                 em.error("initialization with `%s.%s+1` causes overflow for type `%s`",
 2656                     emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars());
 2657                 return errorReturn();
 2658             }
 2659 
 2660             // Now set e to (eprev + 1)
 2661             e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
 2662             e = e.expressionSemantic(sc);
 2663             e = e.castTo(sc, eprev.type);
 2664             e = e.ctfeInterpret();
 2665 
 2666             // save origValue (without cast) for better json output
 2667             if (e.op != TOK.error) // avoid duplicate diagnostics
 2668             {
 2669                 assert(emprev.origValue);
 2670                 em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
 2671                 em.origValue = em.origValue.expressionSemantic(sc);
 2672                 em.origValue = em.origValue.ctfeInterpret();
 2673             }
 2674 
 2675             if (e.op == TOK.error)
 2676                 return errorReturn();
 2677             if (e.type.isfloating())
 2678             {
 2679                 // Check that e != eprev (not always true for floats)
 2680                 Expression etest = new EqualExp(TOK.equal, em.loc, e, eprev);
 2681                 etest = etest.expressionSemantic(sc);
 2682                 etest = etest.ctfeInterpret();
 2683                 if (etest.toInteger())
 2684                 {
 2685                     em.error("has inexact value due to loss of precision");
 2686                     return errorReturn();
 2687                 }
 2688             }
 2689             em.value = e;
 2690         }
 2691         if (!em.origType)
 2692             em.type = em.value.type;
 2693 
 2694         assert(em.origValue);
 2695         em.semanticRun = PASS.semanticdone;
 2696     }
 2697 
 2698     override void visit(TemplateDeclaration tempdecl)
 2699     {
 2700         static if (LOG)
 2701         {
 2702             printf("TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\n", this, tempdecl.ident.toChars());
 2703             printf("sc.stc = %llx\n", sc.stc);
 2704             printf("sc.module = %s\n", sc._module.toChars());
 2705         }
 2706         if (tempdecl.semanticRun != PASS.init)
 2707             return; // semantic() already run
 2708 
 2709         if (tempdecl._scope)
 2710         {
 2711             sc = tempdecl._scope;
 2712             tempdecl._scope = null;
 2713         }
 2714         if (!sc)
 2715             return;
 2716 
 2717         // Remember templates defined in module object that we need to know about
 2718         if (sc._module && sc._module.ident == Id.object)
 2719         {
 2720             if (tempdecl.ident == Id.RTInfo)
 2721                 Type.rtinfo = tempdecl;
 2722         }
 2723 
 2724         /* Remember Scope for later instantiations, but make
 2725          * a copy since attributes can change.
 2726          */
 2727         if (!tempdecl._scope)
 2728         {
 2729             tempdecl._scope = sc.copy();
 2730             tempdecl._scope.setNoFree();
 2731         }
 2732 
 2733         tempdecl.semanticRun = PASS.semantic;
 2734 
 2735         tempdecl.parent = sc.parent;
 2736         tempdecl.protection = sc.protection;
 2737         tempdecl.cppnamespace = sc.namespace;
 2738         tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);
 2739         tempdecl.deprecated_ = !!(sc.stc & STC.deprecated_);
 2740 
 2741         UserAttributeDeclaration.checkGNUABITag(tempdecl, sc.linkage);
 2742 
 2743         if (!tempdecl.isstatic)
 2744         {
 2745             if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())
 2746                 ad.makeNested();
 2747         }
 2748 
 2749         // Set up scope for parameters
 2750         auto paramsym = new ScopeDsymbol();
 2751         paramsym.parent = tempdecl.parent;
 2752         Scope* paramscope = sc.push(paramsym);
 2753         paramscope.stc = 0;
 2754 
 2755         if (global.params.doDocComments)
 2756         {
 2757             tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);
 2758             for (size_t i = 0; i < tempdecl.parameters.dim; i++)
 2759             {
 2760                 TemplateParameter tp = (*tempdecl.parameters)[i];
 2761                 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
 2762             }
 2763         }
 2764 
 2765         for (size_t i = 0; i < tempdecl.parameters.dim; i++)
 2766         {
 2767             TemplateParameter tp = (*tempdecl.parameters)[i];
 2768             if (!tp.declareParameter(paramscope))
 2769             {
 2770                 error(tp.loc, "parameter `%s` multiply defined", tp.ident.toChars());
 2771                 tempdecl.errors = true;
 2772             }
 2773             if (!tp.tpsemantic(paramscope, tempdecl.parameters))
 2774             {
 2775                 tempdecl.errors = true;
 2776             }
 2777             if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())
 2778             {
 2779                 tempdecl.error("template tuple parameter must be last one");
 2780                 tempdecl.errors = true;
 2781             }
 2782         }
 2783 
 2784         /* Calculate TemplateParameter.dependent
 2785          */
 2786         TemplateParameters tparams = TemplateParameters(1);
 2787         for (size_t i = 0; i < tempdecl.parameters.dim; i++)
 2788         {
 2789             TemplateParameter tp = (*tempdecl.parameters)[i];
 2790             tparams[0] = tp;
 2791 
 2792             for (size_t j = 0; j < tempdecl.parameters.dim; j++)
 2793             {
 2794                 // Skip cases like: X(T : T)
 2795                 if (i == j)
 2796                     continue;
 2797 
 2798                 if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())
 2799                 {
 2800                     if (reliesOnTident(ttp.specType, &tparams))
 2801                         tp.dependent = true;
 2802                 }
 2803                 else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())
 2804                 {
 2805                     if (reliesOnTident(tap.specType, &tparams) ||
 2806                         reliesOnTident(isType(tap.specAlias), &tparams))
 2807                     {
 2808                         tp.dependent = true;
 2809                     }
 2810                 }
 2811             }
 2812         }
 2813 
 2814         paramscope.pop();
 2815 
 2816         // Compute again
 2817         tempdecl.onemember = null;
 2818         if (tempdecl.members)
 2819         {
 2820             Dsymbol s;
 2821             if (Dsymbol.oneMembers(tempdecl.members, &s, tempdecl.ident) && s)
 2822             {
 2823                 tempdecl.onemember = s;
 2824                 s.parent = tempdecl;
 2825             }
 2826         }
 2827 
 2828         /* BUG: should check:
 2829          *  1. template functions must not introduce virtual functions, as they
 2830          *     cannot be accomodated in the vtbl[]
 2831          *  2. templates cannot introduce non-static data members (i.e. fields)
 2832          *     as they would change the instance size of the aggregate.
 2833          */
 2834 
 2835         tempdecl.semanticRun = PASS.semanticdone;
 2836     }
 2837 
 2838     override void visit(TemplateInstance ti)
 2839     {
 2840         templateInstanceSemantic(ti, sc, null);
 2841     }
 2842 
 2843     override void visit(TemplateMixin tm)
 2844     {
 2845         static if (LOG)
 2846         {
 2847             printf("+TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
 2848             fflush(stdout);
 2849         }
 2850         if (tm.semanticRun != PASS.init)
 2851         {
 2852             // When a class/struct contains mixin members, and is done over
 2853             // because of forward references, never reach here so semanticRun
 2854             // has been reset to PASS.init.
 2855             static if (LOG)
 2856             {
 2857                 printf("\tsemantic done\n");
 2858             }
 2859             return;
 2860         }
 2861         tm.semanticRun = PASS.semantic;
 2862         static if (LOG)
 2863         {
 2864             printf("\tdo semantic\n");
 2865         }
 2866 
 2867         Scope* scx = null;
 2868         if (tm._scope)
 2869         {
 2870             sc = tm._scope;
 2871             scx = tm._scope; // save so we don't make redundant copies
 2872             tm._scope = null;
 2873         }
 2874 
 2875         /* Run semantic on each argument, place results in tiargs[],
 2876          * then find best match template with tiargs
 2877          */
 2878         if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, null))
 2879         {
 2880             if (tm.semanticRun == PASS.init) // forward reference had occurred
 2881             {
 2882                 //printf("forward reference - deferring\n");
 2883                 return deferDsymbolSemantic(tm, scx);
 2884             }
 2885 
 2886             tm.inst = tm;
 2887             tm.errors = true;
 2888             return; // error recovery
 2889         }
 2890 
 2891         auto tempdecl = tm.tempdecl.isTemplateDeclaration();
 2892         assert(tempdecl);
 2893 
 2894         if (!tm.ident)
 2895         {
 2896             /* Assign scope local unique identifier, as same as lambdas.
 2897              */
 2898             const(char)[] s = "__mixin";
 2899 
 2900             if (FuncDeclaration func = sc.parent.isFuncDeclaration())
 2901             {
 2902                 tm.symtab = func.localsymtab;
 2903                 if (tm.symtab)
 2904                 {
 2905                     // Inside template constraint, symtab is not set yet.
 2906                     goto L1;
 2907                 }
 2908             }
 2909             else
 2910             {
 2911                 tm.symtab = sc.parent.isScopeDsymbol().symtab;
 2912             L1:
 2913                 assert(tm.symtab);
 2914                 tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
 2915                 tm.symtab.insert(tm);
 2916             }
 2917         }
 2918 
 2919         tm.inst = tm;
 2920         tm.parent = sc.parent;
 2921 
 2922         /* Detect recursive mixin instantiations.
 2923          */
 2924         for (Dsymbol s = tm.parent; s; s = s.parent)
 2925         {
 2926             //printf("\ts = '%s'\n", s.toChars());
 2927             TemplateMixin tmix = s.isTemplateMixin();
 2928             if (!tmix || tempdecl != tmix.tempdecl)
 2929                 continue;
 2930 
 2931             /* Different argument list lengths happen with variadic args
 2932              */
 2933             if (tm.tiargs.dim != tmix.tiargs.dim)
 2934                 continue;
 2935 
 2936             for (size_t i = 0; i < tm.tiargs.dim; i++)
 2937             {
 2938                 RootObject o = (*tm.tiargs)[i];
 2939                 Type ta = isType(o);
 2940                 Expression ea = isExpression(o);
 2941                 Dsymbol sa = isDsymbol(o);
 2942                 RootObject tmo = (*tmix.tiargs)[i];
 2943                 if (ta)
 2944                 {
 2945                     Type tmta = isType(tmo);
 2946                     if (!tmta)
 2947                         goto Lcontinue;
 2948                     if (!ta.equals(tmta))
 2949                         goto Lcontinue;
 2950                 }
 2951                 else if (ea)
 2952                 {
 2953                     Expression tme = isExpression(tmo);
 2954                     if (!tme || !ea.equals(tme))
 2955                         goto Lcontinue;
 2956                 }
 2957                 else if (sa)
 2958                 {
 2959                     Dsymbol tmsa = isDsymbol(tmo);
 2960                     if (sa != tmsa)
 2961                         goto Lcontinue;
 2962                 }
 2963                 else
 2964                     assert(0);
 2965             }
 2966             tm.error("recursive mixin instantiation");
 2967             return;
 2968 
 2969         Lcontinue:
 2970             continue;
 2971         }
 2972 
 2973         // Copy the syntax trees from the TemplateDeclaration
 2974         tm.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
 2975         if (!tm.members)
 2976             return;
 2977 
 2978         tm.symtab = new DsymbolTable();
 2979 
 2980         for (Scope* sce = sc; 1; sce = sce.enclosing)
 2981         {
 2982             ScopeDsymbol sds = sce.scopesym;
 2983             if (sds)
 2984             {
 2985                 sds.importScope(tm, Prot(Prot.Kind.public_));
 2986                 break;
 2987             }
 2988         }
 2989 
 2990         static if (LOG)
 2991         {
 2992             printf("\tcreate scope for template parameters '%s'\n", tm.toChars());
 2993         }
 2994         Scope* scy = sc.push(tm);
 2995         scy.parent = tm;
 2996 
 2997         /* https://issues.dlang.org/show_bug.cgi?id=930
 2998          *
 2999          * If the template that is to be mixed in is in the scope of a template
 3000          * instance, we have to also declare the type aliases in the new mixin scope.
 3001          */
 3002         auto parentInstance = tempdecl.parent ? tempdecl.parent.isTemplateInstance() : null;
 3003         if (parentInstance)
 3004             parentInstance.declareParameters(scy);
 3005 
 3006         tm.argsym = new ScopeDsymbol();
 3007         tm.argsym.parent = scy.parent;
 3008         Scope* argscope = scy.push(tm.argsym);
 3009 
 3010         uint errorsave = global.errors;
 3011 
 3012         // Declare each template parameter as an alias for the argument type
 3013         tm.declareParameters(argscope);
 3014 
 3015         // Add members to enclosing scope, as well as this scope
 3016         tm.members.foreachDsymbol(s => s.addMember(argscope, tm));
 3017 
 3018         // Do semantic() analysis on template instance members
 3019         static if (LOG)
 3020         {
 3021             printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
 3022         }
 3023         Scope* sc2 = argscope.push(tm);
 3024         //size_t deferred_dim = Module.deferred.dim;
 3025 
 3026         __gshared int nest;
 3027         //printf("%d\n", nest);
 3028         if (++nest > global.recursionLimit)
 3029         {
 3030             global.gag = 0; // ensure error message gets printed
 3031             tm.error("recursive expansion");
 3032             fatal();
 3033         }
 3034 
 3035         tm.members.foreachDsymbol( s => s.setScope(sc2) );
 3036 
 3037         tm.members.foreachDsymbol( s => s.importAll(sc2) );
 3038 
 3039         tm.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
 3040 
 3041         nest--;
 3042 
 3043         /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
 3044          * Because the members would already call Module.addDeferredSemantic() for themselves.
 3045          * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
 3046          */
 3047         //if (!sc.func && Module.deferred.dim > deferred_dim) {}
 3048 
 3049         AggregateDeclaration ad = tm.toParent().isAggregateDeclaration();
 3050         if (sc.func && !ad)
 3051         {
 3052             tm.semantic2(sc2);
 3053             tm.semantic3(sc2);
 3054         }
 3055 
 3056         // Give additional context info if error occurred during instantiation
 3057         if (global.errors != errorsave)
 3058         {
 3059             tm.error("error instantiating");
 3060             tm.errors = true;
 3061         }
 3062 
 3063         sc2.pop();
 3064         argscope.pop();
 3065         scy.pop();
 3066 
 3067         static if (LOG)
 3068         {
 3069             printf("-TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
 3070         }
 3071     }
 3072 
 3073     override void visit(Nspace ns)
 3074     {
 3075         if (ns.semanticRun != PASS.init)
 3076             return;
 3077         static if (LOG)
 3078         {
 3079             printf("+Nspace::semantic('%s')\n", ns.toChars());
 3080         }
 3081         if (ns._scope)
 3082         {
 3083             sc = ns._scope;
 3084             ns._scope = null;
 3085         }
 3086         if (!sc)
 3087             return;
 3088 
 3089         bool repopulateMembers = false;
 3090         if (ns.identExp)
 3091         {
 3092             // resolve the namespace identifier
 3093             sc = sc.startCTFE();
 3094             Expression resolved = ns.identExp.expressionSemantic(sc);
 3095             resolved = resolveProperties(sc, resolved);
 3096             sc = sc.endCTFE();
 3097             resolved = resolved.ctfeInterpret();
 3098             StringExp name = resolved.toStringExp();
 3099             TupleExp tup = name ? null : resolved.toTupleExp();
 3100             if (!tup && !name)
 3101             {
 3102                 error(ns.loc, "expected string expression for namespace name, got `%s`", ns.identExp.toChars());
 3103                 return;
 3104             }
 3105             ns.identExp = resolved; // we don't need to keep the old AST around
 3106             if (name)
 3107             {
 3108                 const(char)[] ident = name.toStringz();
 3109                 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
 3110                 {
 3111                     error(ns.loc, "expected valid identifer for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
 3112                     return;
 3113                 }
 3114                 ns.ident = Identifier.idPool(ident);
 3115             }
 3116             else
 3117             {
 3118                 // create namespace stack from the tuple
 3119                 Nspace parentns = ns;
 3120                 foreach (i, exp; *tup.exps)
 3121                 {
 3122                     name = exp.toStringExp();
 3123                     if (!name)
 3124                     {
 3125                         error(ns.loc, "expected string expression for namespace name, got `%s`", exp.toChars());
 3126                         return;
 3127                     }
 3128                     const(char)[] ident = name.toStringz();
 3129                     if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
 3130                     {
 3131                         error(ns.loc, "expected valid identifer for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
 3132                         return;
 3133                     }
 3134                     if (i == 0)
 3135                     {
 3136                         ns.ident = Identifier.idPool(ident);
 3137                     }
 3138                     else
 3139                     {
 3140                         // insert the new namespace
 3141                         Nspace childns = new Nspace(ns.loc, Identifier.idPool(ident), null, parentns.members);
 3142                         parentns.members = new Dsymbols;
 3143                         parentns.members.push(childns);
 3144                         parentns = childns;
 3145                         repopulateMembers = true;
 3146                     }
 3147                 }
 3148             }
 3149         }
 3150 
 3151         ns.semanticRun = PASS.semantic;
 3152         ns.parent = sc.parent;
 3153         // Link does not matter here, if the UDA is present it will error
 3154         UserAttributeDeclaration.checkGNUABITag(ns, LINK.cpp);
 3155 
 3156         if (ns.members)
 3157         {
 3158             assert(sc);
 3159             sc = sc.push(ns);
 3160             sc.linkage = LINK.cpp; // note that namespaces imply C++ linkage
 3161             sc.parent = ns;
 3162             foreach (s; *ns.members)
 3163             {
 3164                 if (repopulateMembers)
 3165                 {
 3166                     s.addMember(sc, sc.scopesym);
 3167                     s.setScope(sc);
 3168                 }
 3169                 s.importAll(sc);
 3170             }
 3171             foreach (s; *ns.members)
 3172             {
 3173                 static if (LOG)
 3174                 {
 3175                     printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
 3176                 }
 3177                 s.dsymbolSemantic(sc);
 3178             }
 3179             sc.pop();
 3180         }
 3181         ns.semanticRun = PASS.semanticdone;
 3182         static if (LOG)
 3183         {
 3184             printf("-Nspace::semantic('%s')\n", ns.toChars());
 3185         }
 3186     }
 3187 
 3188     void funcDeclarationSemantic(FuncDeclaration funcdecl)
 3189     {
 3190         TypeFunction f;
 3191         AggregateDeclaration ad;
 3192         InterfaceDeclaration id;
 3193 
 3194         version (none)
 3195         {
 3196             printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, funcdecl, funcdecl.toPrettyChars(), sc.linkage);
 3197             if (funcdecl.isFuncLiteralDeclaration())
 3198                 printf("\tFuncLiteralDeclaration()\n");
 3199             printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), funcdecl.parent ? funcdecl.parent.toChars() : "");
 3200             printf("type: %p, %s\n", funcdecl.type, funcdecl.type.toChars());
 3201         }
 3202 
 3203         if (funcdecl.semanticRun != PASS.init && funcdecl.isFuncLiteralDeclaration())
 3204         {
 3205             /* Member functions that have return types that are
 3206              * forward references can have semantic() run more than
 3207              * once on them.
 3208              * See test\interface2.d, test20
 3209              */
 3210             return;
 3211         }
 3212 
 3213         if (funcdecl.semanticRun >= PASS.semanticdone)
 3214             return;
 3215         assert(funcdecl.semanticRun <= PASS.semantic);
 3216         funcdecl.semanticRun = PASS.semantic;
 3217 
 3218         if (funcdecl._scope)
 3219         {
 3220             sc = funcdecl._scope;
 3221             funcdecl._scope = null;
 3222         }
 3223 
 3224         if (!sc || funcdecl.errors)
 3225             return;
 3226 
 3227         funcdecl.cppnamespace = sc.namespace;
 3228         funcdecl.parent = sc.parent;
 3229         Dsymbol parent = funcdecl.toParent();
 3230 
 3231         funcdecl.foverrides.setDim(0); // reset in case semantic() is being retried for this function
 3232 
 3233         funcdecl.storage_class |= sc.stc & ~STC.ref_;
 3234         ad = funcdecl.isThis();
 3235         // Don't nest structs b/c of generated methods which should not access the outer scopes.
 3236         // https://issues.dlang.org/show_bug.cgi?id=16627
 3237         if (ad && !funcdecl.generated)
 3238         {
 3239             funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_);
 3240             ad.makeNested();
 3241         }
 3242         if (sc.func)
 3243             funcdecl.storage_class |= sc.func.storage_class & STC.disable;
 3244         // Remove prefix storage classes silently.
 3245         if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
 3246             funcdecl.storage_class &= ~STC.TYPECTOR;
 3247 
 3248         //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration::isFinal());
 3249 
 3250         if (sc.flags & SCOPE.compile)
 3251             funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
 3252 
 3253         FuncLiteralDeclaration fld = funcdecl.isFuncLiteralDeclaration();
 3254         if (fld && fld.treq)
 3255         {
 3256             Type treq = fld.treq;
 3257             assert(treq.nextOf().ty == Tfunction);
 3258             if (treq.ty == Tdelegate)
 3259                 fld.tok = TOK.delegate_;
 3260             else if (treq.ty == Tpointer && treq.nextOf().ty == Tfunction)
 3261                 fld.tok = TOK.function_;
 3262             else
 3263                 assert(0);
 3264             funcdecl.linkage = treq.nextOf().toTypeFunction().linkage;
 3265         }
 3266         else
 3267             funcdecl.linkage = sc.linkage;
 3268         funcdecl.inlining = sc.inlining;
 3269         funcdecl.protection = sc.protection;
 3270         funcdecl.userAttribDecl = sc.userAttribDecl;
 3271         UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage);
 3272 
 3273         if (!funcdecl.originalType)
 3274             funcdecl.originalType = funcdecl.type.syntaxCopy();
 3275         if (funcdecl.type.ty != Tfunction)
 3276         {
 3277             if (funcdecl.type.ty != Terror)
 3278             {
 3279                 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
 3280                 funcdecl.type = Type.terror;
 3281             }
 3282             funcdecl.errors = true;
 3283             return;
 3284         }
 3285         if (!funcdecl.type.deco)
 3286         {
 3287             sc = sc.push();
 3288             sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
 3289 
 3290             TypeFunction tf = funcdecl.type.toTypeFunction();
 3291             if (sc.func)
 3292             {
 3293                 /* If the nesting parent is pure without inference,
 3294                  * then this function defaults to pure too.
 3295                  *
 3296                  *  auto foo() pure {
 3297                  *    auto bar() {}     // become a weak purity function
 3298                  *    class C {         // nested class
 3299                  *      auto baz() {}   // become a weak purity function
 3300                  *    }
 3301                  *
 3302                  *    static auto boo() {}   // typed as impure
 3303                  *    // Even though, boo cannot call any impure functions.
 3304                  *    // See also Expression::checkPurity().
 3305                  *  }
 3306                  */
 3307                 if (tf.purity == PURE.impure && (funcdecl.isNested() || funcdecl.isThis()))
 3308                 {
 3309                     FuncDeclaration fd = null;
 3310                     for (Dsymbol p = funcdecl.toParent2(); p; p = p.toParent2())
 3311                     {
 3312                         if (AggregateDeclaration adx = p.isAggregateDeclaration())
 3313                         {
 3314                             if (adx.isNested())
 3315                                 continue;
 3316                             break;
 3317                         }
 3318                         if ((fd = p.isFuncDeclaration()) !is null)
 3319                             break;
 3320                     }
 3321 
 3322                     /* If the parent's purity is inferred, then this function's purity needs
 3323                      * to be inferred first.
 3324                      */
 3325                     if (fd && fd.isPureBypassingInference() >= PURE.weak && !funcdecl.isInstantiated())
 3326                     {
 3327                         tf.purity = PURE.fwdref; // default to pure
 3328                     }
 3329                 }
 3330             }
 3331 
 3332             if (tf.isref)
 3333                 sc.stc |= STC.ref_;
 3334             if (tf.isScopeQual)
 3335                 sc.stc |= STC.scope_;
 3336             if (tf.isnothrow)
 3337                 sc.stc |= STC.nothrow_;
 3338             if (tf.isnogc)
 3339                 sc.stc |= STC.nogc;
 3340             if (tf.isproperty)
 3341                 sc.stc |= STC.property;
 3342             if (tf.purity == PURE.fwdref)
 3343                 sc.stc |= STC.pure_;
 3344             if (tf.trust != TRUST.default_)
 3345                 sc.stc &= ~STC.safeGroup;
 3346             if (tf.trust == TRUST.safe)
 3347                 sc.stc |= STC.safe;
 3348             if (tf.trust == TRUST.system)
 3349                 sc.stc |= STC.system;
 3350             if (tf.trust == TRUST.trusted)
 3351                 sc.stc |= STC.trusted;
 3352 
 3353             if (funcdecl.isCtorDeclaration())
 3354             {
 3355                 sc.flags |= SCOPE.ctor;
 3356                 Type tret = ad.handleType();
 3357                 assert(tret);
 3358                 tret = tret.addStorageClass(funcdecl.storage_class | sc.stc);
 3359                 tret = tret.addMod(funcdecl.type.mod);
 3360                 tf.next = tret;
 3361                 if (ad.isStructDeclaration())
 3362                     sc.stc |= STC.ref_;
 3363             }
 3364 
 3365             // 'return' on a non-static class member function implies 'scope' as well
 3366             if (ad && ad.isClassDeclaration() && (tf.isreturn || sc.stc & STC.return_) && !(sc.stc & STC.static_))
 3367                 sc.stc |= STC.scope_;
 3368 
 3369             // If 'this' has no pointers, remove 'scope' as it has no meaning
 3370             if (sc.stc & STC.scope_ && ad && ad.isStructDeclaration() && !ad.type.hasPointers())
 3371             {
 3372                 sc.stc &= ~STC.scope_;
 3373                 tf.isScopeQual = false;
 3374             }
 3375 
 3376             sc.linkage = funcdecl.linkage;
 3377 
 3378             if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
 3379             {
 3380                 OutBuffer buf;
 3381                 MODtoBuffer(&buf, tf.mod);
 3382                 funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
 3383                 tf.mod = 0; // remove qualifiers
 3384             }
 3385 
 3386             /* Apply const, immutable, wild and shared storage class
 3387              * to the function type. Do this before type semantic.
 3388              */
 3389             auto stc = funcdecl.storage_class;
 3390             if (funcdecl.type.isImmutable())
 3391                 stc |= STC.immutable_;
 3392             if (funcdecl.type.isConst())
 3393                 stc |= STC.const_;
 3394             if (funcdecl.type.isShared() || funcdecl.storage_class & STC.synchronized_)
 3395                 stc |= STC.shared_;
 3396             if (funcdecl.type.isWild())
 3397                 stc |= STC.wild;
 3398             funcdecl.type = funcdecl.type.addSTC(stc);
 3399 
 3400             funcdecl.type = funcdecl.type.typeSemantic(funcdecl.loc, sc);
 3401             sc = sc.pop();
 3402         }
 3403         if (funcdecl.type.ty != Tfunction)
 3404         {
 3405             if (funcdecl.type.ty != Terror)
 3406             {
 3407                 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
 3408                 funcdecl.type = Type.terror;
 3409             }
 3410             funcdecl.errors = true;
 3411             return;
 3412         }
 3413         else
 3414         {
 3415             // Merge back function attributes into 'originalType'.
 3416             // It's used for mangling, ddoc, and json output.
 3417             TypeFunction tfo = funcdecl.originalType.toTypeFunction();
 3418             TypeFunction tfx = funcdecl.type.toTypeFunction();
 3419             tfo.mod = tfx.mod;
 3420             tfo.isScopeQual = tfx.isScopeQual;
 3421             tfo.isreturninferred = tfx.isreturninferred;
 3422             tfo.isscopeinferred = tfx.isscopeinferred;
 3423             tfo.isref = tfx.isref;
 3424             tfo.isnothrow = tfx.isnothrow;
 3425             tfo.isnogc = tfx.isnogc;
 3426             tfo.isproperty = tfx.isproperty;
 3427             tfo.purity = tfx.purity;
 3428             tfo.trust = tfx.trust;
 3429 
 3430             funcdecl.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);
 3431         }
 3432 
 3433         f = cast(TypeFunction)funcdecl.type;
 3434 
 3435         if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)
 3436             funcdecl.error("storage class `auto` has no effect if return type is not inferred");
 3437 
 3438         /* Functions can only be 'scope' if they have a 'this'
 3439          */
 3440         if (f.isScopeQual && !funcdecl.isNested() && !ad)
 3441         {
 3442             funcdecl.error("functions cannot be `scope`");
 3443         }
 3444 
 3445         if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())
 3446         {
 3447             /* Non-static nested functions have a hidden 'this' pointer to which
 3448              * the 'return' applies
 3449              */
 3450             if (sc.scopesym && sc.scopesym.isAggregateDeclaration())
 3451                 funcdecl.error("`static` member has no `this` to which `return` can apply");
 3452             else
 3453                 error(funcdecl.loc, "Top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars());
 3454         }
 3455 
 3456         if (funcdecl.isAbstract() && !funcdecl.isVirtual())
 3457         {
 3458             const(char)* sfunc;
 3459             if (funcdecl.isStatic())
 3460                 sfunc = "static";
 3461             else if (funcdecl.protection.kind == Prot.Kind.private_ || funcdecl.protection.kind == Prot.Kind.package_)
 3462                 sfunc = protectionToChars(funcdecl.protection.kind);
 3463             else
 3464                 sfunc = "final";
 3465             funcdecl.error("`%s` functions cannot be `abstract`", sfunc);
 3466         }
 3467 
 3468         if (funcdecl.isOverride() && !funcdecl.isVirtual() && !funcdecl.isFuncLiteralDeclaration())
 3469         {
 3470             Prot.Kind kind = funcdecl.prot().kind;
 3471             if ((kind == Prot.Kind.private_ || kind == Prot.Kind.package_) && funcdecl.isMember())
 3472                 funcdecl.error("`%s` method is not virtual and cannot override", protectionToChars(kind));
 3473             else
 3474                 funcdecl.error("cannot override a non-virtual function");
 3475         }
 3476 
 3477         if (funcdecl.isAbstract() && funcdecl.isFinalFunc())
 3478             funcdecl.error("cannot be both `final` and `abstract`");
 3479         version (none)
 3480         {
 3481             if (funcdecl.isAbstract() && funcdecl.fbody)
 3482                 funcdecl.error("`abstract` functions cannot have bodies");
 3483         }
 3484 
 3485         version (none)
 3486         {
 3487             if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())
 3488             {
 3489                 if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
 3490                     funcdecl.error("static constructors / destructors must be `static void`");
 3491                 if (f.arguments && f.arguments.dim)
 3492                     funcdecl.error("static constructors / destructors must have empty parameter list");
 3493                 // BUG: check for invalid storage classes
 3494             }
 3495         }
 3496 
 3497         if (const pors = sc.flags & (SCOPE.printf | SCOPE.scanf))
 3498         {
 3499             /* printf/scanf-like functions must be of the form:
 3500              *    extern (C/C++) T printf([parameters...], const(char)* format, ...);
 3501              * or:
 3502              *    extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
 3503              */
 3504 
 3505             static bool isPointerToChar(Parameter p)
 3506             {
 3507                 if (auto tptr = p.type.isTypePointer())
 3508                 {
 3509                     return tptr.next.ty == Tchar;
 3510                 }
 3511                 return false;
 3512             }
 3513 
 3514             bool isVa_list(Parameter p)
 3515             {
 3516                 return p.type.equals(target.va_listType(funcdecl.loc, sc));
 3517             }
 3518 
 3519             const nparams = f.parameterList.length;
 3520             if ((f.linkage == LINK.c || f.linkage == LINK.cpp) &&
 3521 
 3522                 (f.parameterList.varargs == VarArg.variadic &&
 3523                  nparams >= 1 &&
 3524                  isPointerToChar(f.parameterList[nparams - 1]) ||
 3525 
 3526                  f.parameterList.varargs == VarArg.none &&
 3527                  nparams >= 2 &&
 3528                  isPointerToChar(f.parameterList[nparams - 2]) &&
 3529                  isVa_list(f.parameterList[nparams - 1])
 3530                 )
 3531                )
 3532             {
 3533                 funcdecl.flags |= (pors == SCOPE.printf) ? FUNCFLAG.printf : FUNCFLAG.scanf;
 3534             }
 3535             else
 3536             {
 3537                 const p = (pors == SCOPE.printf ? Id.printf : Id.scanf).toChars();
 3538                 if (f.parameterList.varargs == VarArg.variadic)
 3539                 {
 3540                     funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`"
 3541                                    ~ " not `%s`",
 3542                         p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
 3543                 }
 3544                 else
 3545                 {
 3546                     funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`",
 3547                         p, f.next.toChars(), funcdecl.toChars());
 3548                 }
 3549             }
 3550         }
 3551 
 3552         id = parent.isInterfaceDeclaration();
 3553         if (id)
 3554         {
 3555             funcdecl.storage_class |= STC.abstract_;
 3556             if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete())
 3557                 funcdecl.error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", id.toChars());
 3558             if (funcdecl.fbody && funcdecl.isVirtual())
 3559                 funcdecl.error("function body only allowed in `final` functions in interface `%s`", id.toChars());
 3560         }
 3561         if (UnionDeclaration ud = parent.isUnionDeclaration())
 3562         {
 3563             if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration())
 3564                 funcdecl.error("destructors, postblits and invariants are not allowed in union `%s`", ud.toChars());
 3565         }
 3566 
 3567         if (StructDeclaration sd = parent.isStructDeclaration())
 3568         {
 3569             if (funcdecl.isCtorDeclaration())
 3570             {
 3571                 goto Ldone;
 3572             }
 3573         }
 3574 
 3575         if (ClassDeclaration cd = parent.isClassDeclaration())
 3576         {
 3577             parent = cd = objc.getParent(funcdecl, cd);
 3578 
 3579             if (funcdecl.isCtorDeclaration())
 3580             {
 3581                 goto Ldone;
 3582             }
 3583 
 3584             if (funcdecl.storage_class & STC.abstract_)
 3585                 cd.isabstract = Abstract.yes;
 3586 
 3587             // if static function, do not put in vtbl[]
 3588             if (!funcdecl.isVirtual())
 3589             {
 3590                 //printf("\tnot virtual\n");
 3591                 goto Ldone;
 3592             }
 3593             // Suppress further errors if the return type is an error
 3594             if (funcdecl.type.nextOf() == Type.terror)
 3595                 goto Ldone;
 3596 
 3597             bool may_override = false;
 3598             for (size_t i = 0; i < cd.baseclasses.dim; i++)
 3599             {
 3600                 BaseClass* b = (*cd.baseclasses)[i];
 3601                 ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
 3602                 if (!cbd)
 3603                     continue;
 3604                 for (size_t j = 0; j < cbd.vtbl.dim; j++)
 3605                 {
 3606                     FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
 3607                     if (!f2 || f2.ident != funcdecl.ident)
 3608                         continue;
 3609                     if (cbd.parent && cbd.parent.isTemplateInstance())
 3610                     {
 3611                         if (!f2.functionSemantic())
 3612                             goto Ldone;
 3613                     }
 3614                     may_override = true;
 3615                 }
 3616             }
 3617             if (may_override && funcdecl.type.nextOf() is null)
 3618             {
 3619                 /* If same name function exists in base class but 'this' is auto return,
 3620                  * cannot find index of base class's vtbl[] to override.
 3621                  */
 3622                 funcdecl.error("return type inference is not supported if may override base class function");
 3623             }
 3624 
 3625             /* Find index of existing function in base class's vtbl[] to override
 3626              * (the index will be the same as in cd's current vtbl[])
 3627              */
 3628             int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;
 3629 
 3630             bool doesoverride = false;
 3631             switch (vi)
 3632             {
 3633             case -1:
 3634             Lintro:
 3635                 /* Didn't find one, so
 3636                  * This is an 'introducing' function which gets a new
 3637                  * slot in the vtbl[].
 3638                  */
 3639 
 3640                 // Verify this doesn't override previous final function
 3641                 if (cd.baseClass)
 3642                 {
 3643                     Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
 3644                     if (s)
 3645                     {
 3646                         FuncDeclaration f2 = s.isFuncDeclaration();
 3647                         if (f2)
 3648                         {
 3649                             f2 = f2.overloadExactMatch(funcdecl.type);
 3650                             if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)
 3651                                 funcdecl.error("cannot override `final` function `%s`", f2.toPrettyChars());
 3652                         }
 3653                     }
 3654                 }
 3655 
 3656                 /* These quirky conditions mimic what VC++ appears to do
 3657                  */
 3658                 if (global.params.mscoff && cd.classKind == ClassKind.cpp &&
 3659                     cd.baseClass && cd.baseClass.vtbl.dim)
 3660                 {
 3661                     /* if overriding an interface function, then this is not
 3662                      * introducing and don't put it in the class vtbl[]
 3663                      */
 3664                     funcdecl.interfaceVirtual = funcdecl.overrideInterface();
 3665                     if (funcdecl.interfaceVirtual)
 3666                     {
 3667                         //printf("\tinterface function %s\n", toChars());
 3668                         cd.vtblFinal.push(funcdecl);
 3669                         goto Linterfaces;
 3670                     }
 3671                 }
 3672 
 3673                 if (funcdecl.isFinalFunc())
 3674                 {
 3675                     // Don't check here, as it may override an interface function
 3676                     //if (isOverride())
 3677                     //    error("is marked as override, but does not override any function");
 3678                     cd.vtblFinal.push(funcdecl);
 3679                 }
 3680                 else
 3681                 {
 3682                     //printf("\tintroducing function %s\n", funcdecl.toChars());
 3683                     funcdecl.introducing = 1;
 3684                     if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
 3685                     {
 3686                         /* Overloaded functions with same name are grouped and in reverse order.
 3687                          * Search for first function of overload group, and insert
 3688                          * funcdecl into vtbl[] immediately before it.
 3689                          */
 3690                         funcdecl.vtblIndex = cast(int)cd.vtbl.dim;
 3691                         bool found;
 3692                         foreach (const i, s; cd.vtbl)
 3693                         {
 3694                             if (found)
 3695                                 // the rest get shifted forward
 3696                                 ++s.isFuncDeclaration().vtblIndex;
 3697                             else if (s.ident == funcdecl.ident && s.parent == parent)
 3698                             {
 3699                                 // found first function of overload group
 3700                                 funcdecl.vtblIndex = cast(int)i;
 3701                                 found = true;
 3702                                 ++s.isFuncDeclaration().vtblIndex;
 3703                             }
 3704                         }
 3705                         cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
 3706 
 3707                         debug foreach (const i, s; cd.vtbl)
 3708                         {
 3709                             // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
 3710                             // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
 3711                             if (auto fd = s.isFuncDeclaration())
 3712                                 assert(fd.vtblIndex == i ||
 3713                                        (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
 3714                                        funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
 3715                         }
 3716                     }
 3717                     else
 3718                     {
 3719                         // Append to end of vtbl[]
 3720                         vi = cast(int)cd.vtbl.dim;
 3721                         cd.vtbl.push(funcdecl);
 3722                         funcdecl.vtblIndex = vi;
 3723                     }
 3724                 }
 3725                 break;
 3726 
 3727             case -2:
 3728                 // can't determine because of forward references
 3729                 funcdecl.errors = true;
 3730                 return;
 3731 
 3732             default:
 3733                 {
 3734                     FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
 3735                     FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
 3736                     // This function is covariant with fdv
 3737 
 3738                     if (fdc == funcdecl)
 3739                     {
 3740                         doesoverride = true;
 3741                         break;
 3742                     }
 3743 
 3744                     if (fdc.toParent() == parent)
 3745                     {
 3746                         //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc  = %p %s %s @ [%s]\n\tfdv  = %p %s %s @ [%s]\n",
 3747                         //        vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
 3748                         //            fdc,  fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
 3749                         //            fdv,  fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
 3750 
 3751                         // fdc overrides fdv exactly, then this introduces new function.
 3752                         if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
 3753                             goto Lintro;
 3754                     }
 3755 
 3756                     if (fdv.isDeprecated)
 3757                         deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
 3758                                     funcdecl.toPrettyChars, fdv.toPrettyChars);
 3759 
 3760                     // This function overrides fdv
 3761                     if (fdv.isFinalFunc())
 3762                         funcdecl.error("cannot override `final` function `%s`", fdv.toPrettyChars());
 3763 
 3764                     if (!funcdecl.isOverride())
 3765                     {
 3766                         if (fdv.isFuture())
 3767                         {
 3768                             deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars());
 3769                             // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
 3770                             goto Lintro;
 3771                         }
 3772                         else
 3773                         {
 3774                             // https://issues.dlang.org/show_bug.cgi?id=17349
 3775                             error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
 3776                                   fdv.toPrettyChars(), funcdecl.toPrettyChars());
 3777                         }
 3778                     }
 3779                     doesoverride = true;
 3780                     if (fdc.toParent() == parent)
 3781                     {
 3782                         // If both are mixins, or both are not, then error.
 3783                         // If either is not, the one that is not overrides the other.
 3784                         bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
 3785                         bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
 3786                         if (thismixin == fdcmixin)
 3787                         {
 3788                             funcdecl.error("multiple overrides of same function");
 3789                         }
 3790                         /*
 3791                          * https://issues.dlang.org/show_bug.cgi?id=711
 3792                          *
 3793                          * If an overriding method is introduced through a mixin,
 3794                          * we need to update the vtbl so that both methods are
 3795                          * present.
 3796                          */
 3797                         else if (thismixin)
 3798                         {
 3799                             /* if the mixin introduced the overriding method, then reintroduce it
 3800                              * in the vtbl. The initial entry for the mixined method
 3801                              * will be updated at the end of the enclosing `if` block
 3802                              * to point to the current (non-mixined) function.
 3803                              */
 3804                             auto vitmp = cast(int)cd.vtbl.dim;
 3805                             cd.vtbl.push(fdc);
 3806                             fdc.vtblIndex = vitmp;
 3807                         }
 3808                         else if (fdcmixin)
 3809                         {
 3810                             /* if the current overriding function is coming from a
 3811                              * mixined block, then push the current function in the
 3812                              * vtbl, but keep the previous (non-mixined) function as
 3813                              * the overriding one.
 3814                              */
 3815                             auto vitmp = cast(int)cd.vtbl.dim;
 3816                             cd.vtbl.push(funcdecl);
 3817                             funcdecl.vtblIndex = vitmp;
 3818                             break;
 3819                         }
 3820                         else // fdc overrides fdv
 3821                         {
 3822                             // this doesn't override any function
 3823                             break;
 3824                         }
 3825                     }
 3826                     cd.vtbl[vi] = funcdecl;
 3827                     funcdecl.vtblIndex = vi;
 3828 
 3829                     /* Remember which functions this overrides
 3830                      */
 3831                     funcdecl.foverrides.push(fdv);
 3832 
 3833                     /* This works by whenever this function is called,
 3834                      * it actually returns tintro, which gets dynamically
 3835                      * cast to type. But we know that tintro is a base
 3836                      * of type, so we could optimize it by not doing a
 3837                      * dynamic cast, but just subtracting the isBaseOf()
 3838                      * offset if the value is != null.
 3839                      */
 3840 
 3841                     if (fdv.tintro)
 3842                         funcdecl.tintro = fdv.tintro;
 3843                     else if (!funcdecl.type.equals(fdv.type))
 3844                     {
 3845                         /* Only need to have a tintro if the vptr
 3846                          * offsets differ
 3847                          */
 3848                         int offset;
 3849                         if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
 3850                         {
 3851                             funcdecl.tintro = fdv.type;
 3852                         }
 3853                     }
 3854                     break;
 3855                 }
 3856             }
 3857 
 3858             /* Go through all the interface bases.
 3859              * If this function is covariant with any members of those interface
 3860              * functions, set the tintro.
 3861              */
 3862         Linterfaces:
 3863             bool foundVtblMatch = false;
 3864 
 3865             foreach (b; cd.interfaces)
 3866             {
 3867                 vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
 3868                 switch (vi)
 3869                 {
 3870                 case -1:
 3871                     break;
 3872 
 3873                 case -2:
 3874                     // can't determine because of forward references
 3875                     funcdecl.errors = true;
 3876                     return;
 3877 
 3878                 default:
 3879                     {
 3880                         auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
 3881                         Type ti = null;
 3882 
 3883                         foundVtblMatch = true;
 3884 
 3885                         /* Remember which functions this overrides
 3886                          */
 3887                         funcdecl.foverrides.push(fdv);
 3888 
 3889                         /* Should we really require 'override' when implementing
 3890                          * an interface function?
 3891                          */
 3892                         //if (!isOverride())
 3893                         //    warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
 3894 
 3895                         if (fdv.tintro)
 3896                             ti = fdv.tintro;
 3897                         else if (!funcdecl.type.equals(fdv.type))
 3898                         {
 3899                             /* Only need to have a tintro if the vptr
 3900                              * offsets differ
 3901                              */
 3902                             int offset;
 3903                             if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
 3904                             {
 3905                                 ti = fdv.type;
 3906                             }
 3907                         }
 3908                         if (ti)
 3909                         {
 3910                             if (funcdecl.tintro)
 3911                             {
 3912                                 if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
 3913                                 {
 3914                                     funcdecl.error("incompatible covariant types `%s` and `%s`", funcdecl.tintro.toChars(), ti.toChars());
 3915                                 }
 3916                             }
 3917                             else
 3918                             {
 3919                                 funcdecl.tintro = ti;
 3920                             }
 3921                         }
 3922                     }
 3923                 }
 3924             }
 3925             if (foundVtblMatch)
 3926             {
 3927                 goto L2;
 3928             }
 3929 
 3930             if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
 3931             {
 3932                 BaseClass* bc = null;
 3933                 Dsymbol s = null;
 3934                 for (size_t i = 0; i < cd.baseclasses.dim; i++)
 3935                 {
 3936                     bc = (*cd.baseclasses)[i];
 3937                     s = bc.sym.search_correct(funcdecl.ident);
 3938                     if (s)
 3939                         break;
 3940                 }
 3941 
 3942                 if (s)
 3943                 {
 3944                     HdrGenState hgs;
 3945                     OutBuffer buf;
 3946 
 3947                     auto fd = s.isFuncDeclaration();
 3948                     functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
 3949                         new Identifier(funcdecl.toPrettyChars()), &hgs, null);
 3950                     const(char)* funcdeclToChars = buf.peekChars();
 3951 
 3952                     if (fd)
 3953                     {
 3954                         OutBuffer buf1;
 3955 
 3956                         functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
 3957                             new Identifier(fd.toPrettyChars()), &hgs, null);
 3958 
 3959                         error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
 3960                             funcdeclToChars, buf1.peekChars());
 3961                     }
 3962                     else
 3963                     {
 3964                         error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
 3965                             funcdeclToChars, s.kind, s.toPrettyChars());
 3966                         errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overriden");
 3967                     }
 3968                 }
 3969                 else
 3970                     funcdecl.error("does not override any function");
 3971             }
 3972 
 3973         L2:
 3974             objc.setSelector(funcdecl, sc);
 3975             objc.checkLinkage(funcdecl);
 3976             objc.addToClassMethodList(funcdecl, cd);
 3977 
 3978             /* Go through all the interface bases.
 3979              * Disallow overriding any final functions in the interface(s).
 3980              */
 3981             foreach (b; cd.interfaces)
 3982             {
 3983                 if (b.sym)
 3984                 {
 3985                     Dsymbol s = search_function(b.sym, funcdecl.ident);
 3986                     if (s)
 3987                     {
 3988                         FuncDeclaration f2 = s.isFuncDeclaration();
 3989                         if (f2)
 3990                         {
 3991                             f2 = f2.overloadExactMatch(funcdecl.type);
 3992                             if (f2 && f2.isFinalFunc() && f2.prot().kind != Prot.Kind.private_)
 3993                                 funcdecl.error("cannot override `final` function `%s.%s`", b.sym.toChars(), f2.toPrettyChars());
 3994                         }
 3995                     }
 3996                 }
 3997             }
 3998 
 3999             if (funcdecl.isOverride)
 4000             {
 4001                 if (funcdecl.storage_class & STC.disable)
 4002                     deprecation(funcdecl.loc,
 4003                                 "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
 4004                                 funcdecl.toPrettyChars);
 4005                 if (funcdecl.isDeprecated)
 4006                     deprecation(funcdecl.loc,
 4007                                 "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
 4008                                 funcdecl.toPrettyChars);
 4009             }
 4010 
 4011         }
 4012         else if (funcdecl.isOverride() && !parent.isTemplateInstance())
 4013             funcdecl.error("`override` only applies to class member functions");
 4014 
 4015         if (auto ti = parent.isTemplateInstance)
 4016             objc.setSelector(funcdecl, sc);
 4017 
 4018         objc.validateSelector(funcdecl);
 4019         // Reflect this.type to f because it could be changed by findVtblIndex
 4020         f = funcdecl.type.toTypeFunction();
 4021 
 4022     Ldone:
 4023         if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
 4024             funcdecl.error("`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract");
 4025 
 4026         /* Do not allow template instances to add virtual functions
 4027          * to a class.
 4028          */
 4029         if (funcdecl.isVirtual())
 4030         {
 4031             TemplateInstance ti = parent.isTemplateInstance();
 4032             if (ti)
 4033             {
 4034                 // Take care of nested templates
 4035                 while (1)
 4036                 {
 4037                     TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
 4038                     if (!ti2)
 4039                         break;
 4040                     ti = ti2;
 4041                 }
 4042 
 4043                 // If it's a member template
 4044                 ClassDeclaration cd = ti.tempdecl.isClassMember();
 4045                 if (cd)
 4046                 {
 4047                     funcdecl.error("cannot use template to add virtual function to class `%s`", cd.toChars());
 4048                 }
 4049             }
 4050         }
 4051 
 4052         if (funcdecl.isMain())
 4053             funcdecl.checkDmain();       // Check main() parameters and return type
 4054 
 4055         /* Purity and safety can be inferred for some functions by examining
 4056          * the function body.
 4057          */
 4058         if (funcdecl.canInferAttributes(sc))
 4059             funcdecl.initInferAttributes();
 4060 
 4061         Module.dprogress++;
 4062         funcdecl.semanticRun = PASS.semanticdone;
 4063 
 4064         /* Save scope for possible later use (if we need the
 4065          * function internals)
 4066          */
 4067         funcdecl._scope = sc.copy();
 4068         funcdecl._scope.setNoFree();
 4069 
 4070         __gshared bool printedMain = false; // semantic might run more than once
 4071         if (global.params.verbose && !printedMain)
 4072         {
 4073             const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
 4074             Module mod = sc._module;
 4075 
 4076             if (type && mod)
 4077             {
 4078                 printedMain = true;
 4079                 auto name = mod.srcfile.toChars();
 4080                 auto path = FileName.searchPath(global.path, name, true);
 4081                 message("entry     %-10s\t%s", type, path ? path : name);
 4082             }
 4083         }
 4084 
 4085         if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
 4086         {
 4087             // check if `_d_cmain` is defined
 4088             bool cmainTemplateExists()
 4089             {
 4090                 auto rootSymbol = sc.search(funcdecl.loc, Id.empty, null);
 4091                 if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
 4092                     if (moduleSymbol.search(funcdecl.loc, Id.CMain))
 4093                         return true;
 4094 
 4095                 return false;
 4096             }
 4097 
 4098             // Only mixin `_d_cmain` if it is defined
 4099             if (cmainTemplateExists())
 4100             {
 4101                 // add `mixin _d_cmain!();` to the declaring module
 4102                 auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
 4103                 auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
 4104                 sc._module.members.push(tm);
 4105             }
 4106 
 4107             rootHasMain = sc._module;
 4108         }
 4109 
 4110         assert(funcdecl.type.ty != Terror || funcdecl.errors);
 4111 
 4112         // semantic for parameters' UDAs
 4113         foreach (i, param; f.parameterList)
 4114         {
 4115             if (param && param.userAttribDecl)
 4116                 param.userAttribDecl.dsymbolSemantic(sc);
 4117         }
 4118     }
 4119 
 4120      /// Do the semantic analysis on the external interface to the function.
 4121     override void visit(FuncDeclaration funcdecl)
 4122     {
 4123         funcDeclarationSemantic(funcdecl);
 4124     }
 4125 
 4126     override void visit(CtorDeclaration ctd)
 4127     {
 4128         //printf("CtorDeclaration::semantic() %s\n", toChars());
 4129         if (ctd.semanticRun >= PASS.semanticdone)
 4130             return;
 4131         if (ctd._scope)
 4132         {
 4133             sc = ctd._scope;
 4134             ctd._scope = null;
 4135         }
 4136 
 4137         ctd.parent = sc.parent;
 4138         Dsymbol p = ctd.toParentDecl();
 4139         AggregateDeclaration ad = p.isAggregateDeclaration();
 4140         if (!ad)
 4141         {
 4142             error(ctd.loc, "constructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
 4143             ctd.type = Type.terror;
 4144             ctd.errors = true;
 4145             return;
 4146         }
 4147 
 4148         sc = sc.push();
 4149 
 4150         if (sc.stc & STC.static_)
 4151         {
 4152             if (sc.stc & STC.shared_)
 4153                 error(ctd.loc, "`shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`");
 4154             else
 4155                 error(ctd.loc, "`static` has no effect on a constructor inside a `static` block. Use `static this()`");
 4156         }
 4157 
 4158         sc.stc &= ~STC.static_; // not a static constructor
 4159         sc.flags |= SCOPE.ctor;
 4160 
 4161         funcDeclarationSemantic(ctd);
 4162 
 4163         sc.pop();
 4164 
 4165         if (ctd.errors)
 4166             return;
 4167 
 4168         TypeFunction tf = ctd.type.toTypeFunction();
 4169 
 4170         /* See if it's the default constructor
 4171          * But, template constructor should not become a default constructor.
 4172          */
 4173         if (ad && (!ctd.parent.isTemplateInstance() || ctd.parent.isTemplateMixin()))
 4174         {
 4175             immutable dim = tf.parameterList.length;
 4176 
 4177             if (auto sd = ad.isStructDeclaration())
 4178             {
 4179                 if (dim == 0 && tf.parameterList.varargs == VarArg.none) // empty default ctor w/o any varargs
 4180                 {
 4181                     if (ctd.fbody || !(ctd.storage_class & STC.disable))
 4182                     {
 4183                         ctd.error("default constructor for structs only allowed " ~
 4184                             "with `@disable`, no body, and no parameters");
 4185                         ctd.storage_class |= STC.disable;
 4186                         ctd.fbody = null;
 4187                     }
 4188                     sd.noDefaultCtor = true;
 4189                 }
 4190                 else if (dim == 0 && tf.parameterList.varargs != VarArg.none) // allow varargs only ctor
 4191                 {
 4192                 }
 4193                 else if (dim && tf.parameterList[0].defaultArg)
 4194                 {
 4195                     // if the first parameter has a default argument, then the rest does as well
 4196                     if (ctd.storage_class & STC.disable)
 4197                     {
 4198                         ctd.error("is marked `@disable`, so it cannot have default "~
 4199                                   "arguments for all parameters.");
 4200                         errorSupplemental(ctd.loc, "Use `@disable this();` if you want to disable default initialization.");
 4201                     }
 4202                     else
 4203                         ctd.error("all parameters have default arguments, "~
 4204                                   "but structs cannot have default constructors.");
 4205                 }
 4206                 else if ((dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
 4207                 {
 4208                     //printf("tf: %s\n", tf.toChars());
 4209                     auto param = tf.parameterList[0];
 4210                     if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
 4211                     {
 4212                         //printf("copy constructor\n");
 4213                         ctd.isCpCtor = true;
 4214                     }
 4215                 }
 4216             }
 4217             else if (dim == 0 && tf.parameterList.varargs == VarArg.none)
 4218             {
 4219                 ad.defaultCtor = ctd;
 4220             }
 4221         }
 4222     }
 4223 
 4224     override void visit(PostBlitDeclaration pbd)
 4225     {
 4226         //printf("PostBlitDeclaration::semantic() %s\n", toChars());
 4227         //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
 4228         //printf("stc = x%llx\n", sc.stc);
 4229         if (pbd.semanticRun >= PASS.semanticdone)
 4230             return;
 4231         if (pbd._scope)
 4232         {
 4233             sc = pbd._scope;
 4234             pbd._scope = null;
 4235         }
 4236 
 4237         pbd.parent = sc.parent;
 4238         Dsymbol p = pbd.toParent2();
 4239         StructDeclaration ad = p.isStructDeclaration();
 4240         if (!ad)
 4241         {
 4242             error(pbd.loc, "postblit can only be a member of struct, not %s `%s`", p.kind(), p.toChars());
 4243             pbd.type = Type.terror;
 4244             pbd.errors = true;
 4245             return;
 4246         }
 4247         if (pbd.ident == Id.postblit && pbd.semanticRun < PASS.semantic)
 4248             ad.postblits.push(pbd);
 4249         if (!pbd.type)
 4250             pbd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, pbd.storage_class);
 4251 
 4252         sc = sc.push();
 4253         sc.stc &= ~STC.static_; // not static
 4254         sc.linkage = LINK.d;
 4255 
 4256         funcDeclarationSemantic(pbd);
 4257 
 4258         sc.pop();
 4259     }
 4260 
 4261     override void visit(DtorDeclaration dd)
 4262     {
 4263         //printf("DtorDeclaration::semantic() %s\n", toChars());
 4264         //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
 4265         if (dd.semanticRun >= PASS.semanticdone)
 4266             return;
 4267         if (dd._scope)
 4268         {
 4269             sc = dd._scope;
 4270             dd._scope = null;
 4271         }
 4272 
 4273         dd.parent = sc.parent;
 4274         Dsymbol p = dd.toParent2();
 4275         AggregateDeclaration ad = p.isAggregateDeclaration();
 4276         if (!ad)
 4277         {
 4278             error(dd.loc, "destructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
 4279             dd.type = Type.terror;
 4280             dd.errors = true;
 4281             return;
 4282         }
 4283         if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)
 4284             ad.dtors.push(dd);
 4285         if (!dd.type)
 4286         {
 4287             dd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, dd.storage_class);
 4288             if (ad.classKind == ClassKind.cpp && dd.ident == Id.dtor)
 4289             {
 4290                 if (auto cldec = ad.isClassDeclaration())
 4291                 {
 4292                     assert (cldec.cppDtorVtblIndex == -1); // double-call check already by dd.type
 4293                     if (cldec.baseClass && cldec.baseClass.cppDtorVtblIndex != -1)
 4294                     {
 4295                         // override the base virtual
 4296                         cldec.cppDtorVtblIndex = cldec.baseClass.cppDtorVtblIndex;
 4297                     }
 4298                     else if (!dd.isFinal())
 4299                     {
 4300                         // reserve the dtor slot for the destructor (which we'll create later)
 4301                         cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;
 4302                         cldec.vtbl.push(dd);
 4303                         if (target.cpp.twoDtorInVtable)
 4304                             cldec.vtbl.push(dd); // deleting destructor uses a second slot
 4305                     }
 4306                 }
 4307             }
 4308         }
 4309 
 4310         sc = sc.push();
 4311         sc.stc &= ~STC.static_; // not a static destructor
 4312         if (sc.linkage != LINK.cpp)
 4313             sc.linkage = LINK.d;
 4314 
 4315         funcDeclarationSemantic(dd);
 4316 
 4317         sc.pop();
 4318     }
 4319 
 4320     override void visit(StaticCtorDeclaration scd)
 4321     {
 4322         //printf("StaticCtorDeclaration::semantic()\n");
 4323         if (scd.semanticRun >= PASS.semanticdone)
 4324             return;
 4325         if (scd._scope)
 4326         {
 4327             sc = scd._scope;
 4328             scd._scope = null;
 4329         }
 4330 
 4331         scd.parent = sc.parent;
 4332         Dsymbol p = scd.parent.pastMixin();
 4333         if (!p.isScopeDsymbol())
 4334         {
 4335             const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
 4336             error(scd.loc, "`%sstatic` constructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
 4337             scd.type = Type.terror;
 4338             scd.errors = true;
 4339             return;
 4340         }
 4341         if (!scd.type)
 4342             scd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, scd.storage_class);
 4343 
 4344         /* If the static ctor appears within a template instantiation,
 4345          * it could get called multiple times by the module constructors
 4346          * for different modules. Thus, protect it with a gate.
 4347          */
 4348         if (scd.isInstantiated() && scd.semanticRun < PASS.semantic)
 4349         {
 4350             /* Add this prefix to the function:
 4351              *      static int gate;
 4352              *      if (++gate != 1) return;
 4353              * Note that this is not thread safe; should not have threads
 4354              * during static construction.
 4355              */
 4356             auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
 4357             v.storage_class = STC.temp | (scd.isSharedStaticCtorDeclaration() ? STC.static_ : STC.tls);
 4358 
 4359             auto sa = new Statements();
 4360             Statement s = new ExpStatement(Loc.initial, v);
 4361             sa.push(s);
 4362 
 4363             Expression e = new IdentifierExp(Loc.initial, v.ident);
 4364             e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!1);
 4365             e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!1);
 4366             s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
 4367 
 4368             sa.push(s);
 4369             if (scd.fbody)
 4370                 sa.push(scd.fbody);
 4371 
 4372             scd.fbody = new CompoundStatement(Loc.initial, sa);
 4373         }
 4374 
 4375         const LINK save = sc.linkage;
 4376         if (save != LINK.d)
 4377         {
 4378             const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
 4379             deprecation(scd.loc, "`%sstatic` constructor can only be of D linkage", s);
 4380             // Just correct it
 4381             sc.linkage = LINK.d;
 4382         }
 4383         funcDeclarationSemantic(scd);
 4384         sc.linkage = save;
 4385 
 4386         // We're going to need ModuleInfo
 4387         Module m = scd.getModule();
 4388         if (!m)
 4389             m = sc._module;
 4390         if (m)
 4391         {
 4392             m.needmoduleinfo = 1;
 4393             //printf("module1 %s needs moduleinfo\n", m.toChars());
 4394         }
 4395     }
 4396 
 4397     override void visit(StaticDtorDeclaration sdd)
 4398     {
 4399         if (sdd.semanticRun >= PASS.semanticdone)
 4400             return;
 4401         if (sdd._scope)
 4402         {
 4403             sc = sdd._scope;
 4404             sdd._scope = null;
 4405         }
 4406 
 4407         sdd.parent = sc.parent;
 4408         Dsymbol p = sdd.parent.pastMixin();
 4409         if (!p.isScopeDsymbol())
 4410         {
 4411             const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
 4412             error(sdd.loc, "`%sstatic` destructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
 4413             sdd.type = Type.terror;
 4414             sdd.errors = true;
 4415             return;
 4416         }
 4417         if (!sdd.type)
 4418             sdd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, sdd.storage_class);
 4419 
 4420         /* If the static ctor appears within a template instantiation,
 4421          * it could get called multiple times by the module constructors
 4422          * for different modules. Thus, protect it with a gate.
 4423          */
 4424         if (sdd.isInstantiated() && sdd.semanticRun < PASS.semantic)
 4425         {
 4426             /* Add this prefix to the function:
 4427              *      static int gate;
 4428              *      if (--gate != 0) return;
 4429              * Increment gate during constructor execution.
 4430              * Note that this is not thread safe; should not have threads
 4431              * during static destruction.
 4432              */
 4433             auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
 4434             v.storage_class = STC.temp | (sdd.isSharedStaticDtorDeclaration() ? STC.static_ : STC.tls);
 4435 
 4436             auto sa = new Statements();
 4437             Statement s = new ExpStatement(Loc.initial, v);
 4438             sa.push(s);
 4439 
 4440             Expression e = new IdentifierExp(Loc.initial, v.ident);
 4441             e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!(-1));
 4442             e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!0);
 4443             s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
 4444 
 4445             sa.push(s);
 4446             if (sdd.fbody)
 4447                 sa.push(sdd.fbody);
 4448 
 4449             sdd.fbody = new CompoundStatement(Loc.initial, sa);
 4450 
 4451             sdd.vgate = v;
 4452         }
 4453 
 4454         const LINK save = sc.linkage;
 4455         if (save != LINK.d)
 4456         {
 4457             const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
 4458             deprecation(sdd.loc, "`%sstatic` destructor can only be of D linkage", s);
 4459             // Just correct it
 4460             sc.linkage = LINK.d;
 4461         }
 4462         funcDeclarationSemantic(sdd);
 4463         sc.linkage = save;
 4464 
 4465         // We're going to need ModuleInfo
 4466         Module m = sdd.getModule();
 4467         if (!m)
 4468             m = sc._module;
 4469         if (m)
 4470         {
 4471             m.needmoduleinfo = 1;
 4472             //printf("module2 %s needs moduleinfo\n", m.toChars());
 4473         }
 4474     }
 4475 
 4476     override void visit(InvariantDeclaration invd)
 4477     {
 4478         if (invd.semanticRun >= PASS.semanticdone)
 4479             return;
 4480         if (invd._scope)
 4481         {
 4482             sc = invd._scope;
 4483             invd._scope = null;
 4484         }
 4485 
 4486         invd.parent = sc.parent;
 4487         Dsymbol p = invd.parent.pastMixin();
 4488         AggregateDeclaration ad = p.isAggregateDeclaration();
 4489         if (!ad)
 4490         {
 4491             error(invd.loc, "`invariant` can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
 4492             invd.type = Type.terror;
 4493             invd.errors = true;
 4494             return;
 4495         }
 4496         if (invd.ident != Id.classInvariant &&
 4497              invd.semanticRun < PASS.semantic &&
 4498              !ad.isUnionDeclaration()           // users are on their own with union fields
 4499            )
 4500             ad.invs.push(invd);
 4501         if (!invd.type)
 4502             invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class);
 4503 
 4504         sc = sc.push();
 4505         sc.stc &= ~STC.static_; // not a static invariant
 4506         sc.stc |= STC.const_; // invariant() is always const
 4507         sc.flags = (sc.flags & ~SCOPE.contract) | SCOPE.invariant_;
 4508         sc.linkage = LINK.d;
 4509 
 4510         funcDeclarationSemantic(invd);
 4511 
 4512         sc.pop();
 4513     }
 4514 
 4515     override void visit(UnitTestDeclaration utd)
 4516     {
 4517         if (utd.semanticRun >= PASS.semanticdone)
 4518             return;
 4519         if (utd._scope)
 4520         {
 4521             sc = utd._scope;
 4522             utd._scope = null;
 4523         }
 4524 
 4525         utd.protection = sc.protection;
 4526 
 4527         utd.parent = sc.parent;
 4528         Dsymbol p = utd.parent.pastMixin();
 4529         if (!p.isScopeDsymbol())
 4530         {
 4531             error(utd.loc, "`unittest` can only be a member of module/aggregate/template, not %s `%s`", p.kind(), p.toChars());
 4532             utd.type = Type.terror;
 4533             utd.errors = true;
 4534             return;
 4535         }
 4536 
 4537         if (global.params.useUnitTests)
 4538         {
 4539             if (!utd.type)
 4540                 utd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, utd.storage_class);
 4541             Scope* sc2 = sc.push();
 4542             sc2.linkage = LINK.d;
 4543             funcDeclarationSemantic(utd);
 4544             sc2.pop();
 4545         }
 4546 
 4547         version (none)
 4548         {
 4549             // We're going to need ModuleInfo even if the unit tests are not
 4550             // compiled in, because other modules may import this module and refer
 4551             // to this ModuleInfo.
 4552             // (This doesn't make sense to me?)
 4553             Module m = utd.getModule();
 4554             if (!m)
 4555                 m = sc._module;
 4556             if (m)
 4557             {
 4558                 //printf("module3 %s needs moduleinfo\n", m.toChars());
 4559                 m.needmoduleinfo = 1;
 4560             }
 4561         }
 4562     }
 4563 
 4564     override void visit(NewDeclaration nd)
 4565     {
 4566         //printf("NewDeclaration::semantic()\n");
 4567 
 4568         // `@disable new();` should not be deprecated
 4569         if (!nd.isDisabled())
 4570         {
 4571             // @@@DEPRECATED_2.091@@@
 4572             // Made an error in 2.087.
 4573             // Should be removed in 2.091
 4574             error(nd.loc, "class allocators are obsolete, consider moving the allocation strategy outside of the class");
 4575         }
 4576 
 4577         if (nd.semanticRun >= PASS.semanticdone)
 4578             return;
 4579         if (nd._scope)
 4580         {
 4581             sc = nd._scope;
 4582             nd._scope = null;
 4583         }
 4584 
 4585         nd.parent = sc.parent;
 4586         Dsymbol p = nd.parent.pastMixin();
 4587         if (!p.isAggregateDeclaration())
 4588         {
 4589             error(nd.loc, "allocator can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
 4590             nd.type = Type.terror;
 4591             nd.errors = true;
 4592             return;
 4593         }
 4594         Type tret = Type.tvoid.pointerTo();
 4595         if (!nd.type)
 4596             nd.type = new TypeFunction(nd.parameterList, tret, LINK.d, nd.storage_class);
 4597 
 4598         nd.type = nd.type.typeSemantic(nd.loc, sc);
 4599 
 4600         // allow for `@disable new();` to force users of a type to use an external allocation strategy
 4601         if (!nd.isDisabled())
 4602         {
 4603             // Check that there is at least one argument of type size_t
 4604             TypeFunction tf = nd.type.toTypeFunction();
 4605             if (tf.parameterList.length < 1)
 4606             {
 4607                 nd.error("at least one argument of type `size_t` expected");
 4608             }
 4609             else
 4610             {
 4611                 Parameter fparam = tf.parameterList[0];
 4612                 if (!fparam.type.equals(Type.tsize_t))
 4613                     nd.error("first argument must be type `size_t`, not `%s`", fparam.type.toChars());
 4614             }
 4615         }
 4616 
 4617         funcDeclarationSemantic(nd);
 4618     }
 4619 
 4620     /* https://issues.dlang.org/show_bug.cgi?id=19731
 4621      *
 4622      * Some aggregate member functions might have had
 4623      * semantic 3 ran on them despite being in semantic1
 4624      * (e.g. auto functions); if that is the case, then
 4625      * invariants will not be taken into account for them
 4626      * because at the time of the analysis it would appear
 4627      * as if the struct declaration does not have any
 4628      * invariants. To solve this issue, we need to redo
 4629      * semantic3 on the function declaration.
 4630      */
 4631     private void reinforceInvariant(AggregateDeclaration ad, Scope* sc)
 4632     {
 4633         // for each member
 4634         for(int i = 0; i < ad.members.dim; i++)
 4635         {
 4636             if (!(*ad.members)[i])
 4637                 continue;
 4638             auto fd = (*ad.members)[i].isFuncDeclaration();
 4639             if (!fd || fd.generated || fd.semanticRun != PASS.semantic3done)
 4640                 continue;
 4641 
 4642             /* if it's a user defined function declaration and semantic3
 4643              * was already performed on it, create a syntax copy and
 4644              * redo the first semantic step.
 4645              */
 4646             auto fd_temp = fd.syntaxCopy(null).isFuncDeclaration();
 4647             fd_temp.storage_class &= ~STC.auto_; // type has already been inferred
 4648             if (auto cd = ad.isClassDeclaration())
 4649                 cd.vtbl.remove(fd.vtblIndex);
 4650             fd_temp.dsymbolSemantic(sc);
 4651             (*ad.members)[i] = fd_temp;
 4652         }
 4653     }
 4654 
 4655     override void visit(StructDeclaration sd)
 4656     {
 4657         //printf("StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
 4658 
 4659         //static int count; if (++count == 20) assert(0);
 4660 
 4661         if (sd.semanticRun >= PASS.semanticdone)
 4662             return;
 4663         int errors = global.errors;
 4664 
 4665         //printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", this, toPrettyChars(), sizeok);
 4666         Scope* scx = null;
 4667         if (sd._scope)
 4668         {
 4669             sc = sd._scope;
 4670             scx = sd._scope; // save so we don't make redundant copies
 4671             sd._scope = null;
 4672         }
 4673 
 4674         if (!sd.parent)
 4675         {
 4676             assert(sc.parent && sc.func);
 4677             sd.parent = sc.parent;
 4678         }
 4679         assert(sd.parent && !sd.isAnonymous());
 4680 
 4681         if (sd.errors)
 4682             sd.type = Type.terror;
 4683         if (sd.semanticRun == PASS.init)
 4684             sd.type = sd.type.addSTC(sc.stc | sd.storage_class);
 4685         sd.type = sd.type.typeSemantic(sd.loc, sc);
 4686         if (auto ts = sd.type.isTypeStruct())
 4687             if (ts.sym != sd)
 4688             {
 4689                 auto ti = ts.sym.isInstantiated();
 4690                 if (ti && isError(ti))
 4691                     ts.sym = sd;
 4692             }
 4693 
 4694         // Ungag errors when not speculative
 4695         Ungag ungag = sd.ungagSpeculative();
 4696 
 4697         if (sd.semanticRun == PASS.init)
 4698         {
 4699             sd.protection = sc.protection;
 4700 
 4701             sd.alignment = sc.alignment();
 4702 
 4703             sd.storage_class |= sc.stc;
 4704             if (sd.storage_class & STC.abstract_)
 4705                 sd.error("structs, unions cannot be `abstract`");
 4706 
 4707             sd.userAttribDecl = sc.userAttribDecl;
 4708 
 4709             if (sc.linkage == LINK.cpp)
 4710                 sd.classKind = ClassKind.cpp;
 4711             sd.cppnamespace = sc.namespace;
 4712             sd.cppmangle = sc.cppmangle;
 4713         }
 4714         else if (sd.symtab && !scx)
 4715             return;
 4716 
 4717         sd.semanticRun = PASS.semantic;
 4718         UserAttributeDeclaration.checkGNUABITag(sd, sc.linkage);
 4719 
 4720         if (!sd.members) // if opaque declaration
 4721         {
 4722             sd.semanticRun = PASS.semanticdone;
 4723             return;
 4724         }
 4725         if (!sd.symtab)
 4726         {
 4727             sd.symtab = new DsymbolTable();
 4728 
 4729             sd.members.foreachDsymbol( s => s.addMember(sc, sd) );
 4730         }
 4731 
 4732         auto sc2 = sd.newScope(sc);
 4733 
 4734         /* Set scope so if there are forward references, we still might be able to
 4735          * resolve individual members like enums.
 4736          */
 4737         sd.members.foreachDsymbol( s => s.setScope(sc2) );
 4738         sd.members.foreachDsymbol( s => s.importAll(sc2) );
 4739         sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); sd.errors |= s.errors; } );
 4740 
 4741         if (sd.errors)
 4742             sd.type = Type.terror;
 4743 
 4744         if (!sd.determineFields())
 4745         {
 4746             if (sd.type.ty != Terror)
 4747             {
 4748                 sd.error(sd.loc, "circular or forward reference");
 4749                 sd.errors = true;
 4750                 sd.type = Type.terror;
 4751             }
 4752 
 4753             sc2.pop();
 4754             sd.semanticRun = PASS.semanticdone;
 4755             return;
 4756         }
 4757         /* Following special member functions creation needs semantic analysis
 4758          * completion of sub-structs in each field types. For example, buildDtor
 4759          * needs to check existence of elaborate dtor in type of each fields.
 4760          * See the case in compilable/test14838.d
 4761          */
 4762         foreach (v; sd.fields)
 4763         {
 4764             Type tb = v.type.baseElemOf();
 4765             if (tb.ty != Tstruct)
 4766                 continue;
 4767             auto sdec = (cast(TypeStruct)tb).sym;
 4768             if (sdec.semanticRun >= PASS.semanticdone)
 4769                 continue;
 4770 
 4771             sc2.pop();
 4772 
 4773             //printf("\tdeferring %s\n", toChars());
 4774             return deferDsymbolSemantic(sd, scx);
 4775         }
 4776 
 4777         /* Look for special member functions.
 4778          */
 4779         sd.aggNew = cast(NewDeclaration)sd.search(Loc.initial, Id.classNew);
 4780 
 4781         // Look for the constructor
 4782         sd.ctor = sd.searchCtor();
 4783 
 4784         sd.dtor = buildDtor(sd, sc2);
 4785         sd.tidtor = buildExternDDtor(sd, sc2);
 4786         sd.postblit = buildPostBlit(sd, sc2);
 4787         sd.hasCopyCtor = buildCopyCtor(sd, sc2);
 4788 
 4789         buildOpAssign(sd, sc2);
 4790         buildOpEquals(sd, sc2);
 4791 
 4792         if (global.params.useTypeInfo && Type.dtypeinfo)  // these functions are used for TypeInfo
 4793         {
 4794             sd.xeq = buildXopEquals(sd, sc2);
 4795             sd.xcmp = buildXopCmp(sd, sc2);
 4796             sd.xhash = buildXtoHash(sd, sc2);
 4797         }
 4798 
 4799         sd.inv = buildInv(sd, sc2);
 4800         if (sd.inv)
 4801             reinforceInvariant(sd, sc2);
 4802 
 4803         Module.dprogress++;
 4804         sd.semanticRun = PASS.semanticdone;
 4805         //printf("-StructDeclaration::semantic(this=%p, '%s')\n", sd, sd.toChars());
 4806 
 4807         sc2.pop();
 4808 
 4809         if (sd.ctor)
 4810         {
 4811             Dsymbol scall = sd.search(Loc.initial, Id.call);
 4812             if (scall)
 4813             {
 4814                 uint xerrors = global.startGagging();
 4815                 sc = sc.push();
 4816                 sc.tinst = null;
 4817                 sc.minst = null;
 4818                 auto fcall = resolveFuncCall(sd.loc, sc, scall, null, null, null, FuncResolveFlag.quiet);
 4819                 sc = sc.pop();
 4820                 global.endGagging(xerrors);
 4821 
 4822                 if (fcall && fcall.isStatic())
 4823                 {
 4824                     sd.error(fcall.loc, "`static opCall` is hidden by constructors and can never be called");
 4825                     errorSupplemental(fcall.loc, "Please use a factory method instead, or replace all constructors with `static opCall`.");
 4826                 }
 4827             }
 4828         }
 4829 
 4830         if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd)
 4831         {
 4832             // https://issues.dlang.org/show_bug.cgi?id=19024
 4833             StructDeclaration sym = (cast(TypeStruct)sd.type).sym;
 4834             version (none)
 4835             {
 4836                 printf("this = %p %s\n", sd, sd.toChars());
 4837                 printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars());
 4838             }
 4839             sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars());
 4840         }
 4841 
 4842         if (global.errors != errors)
 4843         {
 4844             // The type is no good.
 4845             sd.type = Type.terror;
 4846             sd.errors = true;
 4847             if (sd.deferred)
 4848                 sd.deferred.errors = true;
 4849         }
 4850 
 4851         if (sd.deferred && !global.gag)
 4852         {
 4853             sd.deferred.semantic2(sc);
 4854             sd.deferred.semantic3(sc);
 4855         }
 4856     }
 4857 
 4858     void interfaceSemantic(ClassDeclaration cd)
 4859     {
 4860         cd.vtblInterfaces = new BaseClasses();
 4861         cd.vtblInterfaces.reserve(cd.interfaces.length);
 4862         foreach (b; cd.interfaces)
 4863         {
 4864             cd.vtblInterfaces.push(b);
 4865             b.copyBaseInterfaces(cd.vtblInterfaces);
 4866         }
 4867     }
 4868 
 4869     override void visit(ClassDeclaration cldec)
 4870     {
 4871         /// Checks that the given class implements all methods of its interfaces.
 4872         static void checkInterfaceImplementations(ClassDeclaration cd)
 4873         {
 4874             foreach (base; cd.interfaces)
 4875             {
 4876                 // first entry is ClassInfo reference
 4877                 auto methods = base.sym.vtbl[base.sym.vtblOffset .. $];
 4878 
 4879                 foreach (m; methods)
 4880                 {
 4881                     auto ifd = m.isFuncDeclaration;
 4882                     assert(ifd);
 4883 
 4884                     auto type = ifd.type.toTypeFunction();
 4885                     auto fd = cd.findFunc(ifd.ident, type);
 4886 
 4887                     if (fd && !fd.isAbstract)
 4888                     {
 4889                         //printf("            found\n");
 4890                         // Check that calling conventions match
 4891                         if (fd.linkage != ifd.linkage)
 4892                             fd.error("linkage doesn't match interface function");
 4893 
 4894                         // Check that it is current
 4895                         //printf("newinstance = %d fd.toParent() = %s ifd.toParent() = %s\n",
 4896                             //newinstance, fd.toParent().toChars(), ifd.toParent().toChars());
 4897                         if (fd.toParent() != cd && ifd.toParent() == base.sym)
 4898                             cd.error("interface function `%s` is not implemented", ifd.toFullSignature());
 4899                     }
 4900 
 4901                     else
 4902                     {
 4903                         //printf("            not found %p\n", fd);
 4904                         // BUG: should mark this class as abstract?
 4905                         if (!cd.isAbstract())
 4906                             cd.error("interface function `%s` is not implemented", ifd.toFullSignature());
 4907                     }
 4908                 }
 4909             }
 4910         }
 4911 
 4912         //printf("ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", cldec.toChars(), cldec.type, cldec.sizeok, this);
 4913         //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : "");
 4914         //printf("sc.stc = %x\n", sc.stc);
 4915 
 4916         //{ static int n;  if (++n == 20) *(char*)0=0; }
 4917 
 4918         if (cldec.semanticRun >= PASS.semanticdone)
 4919             return;
 4920         int errors = global.errors;
 4921 
 4922         //printf("+ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
 4923 
 4924         Scope* scx = null;
 4925         if (cldec._scope)
 4926         {
 4927             sc = cldec._scope;
 4928             scx = cldec._scope; // save so we don't make redundant copies
 4929             cldec._scope = null;
 4930         }
 4931 
 4932         if (!cldec.parent)
 4933         {
 4934             assert(sc.parent);
 4935             cldec.parent = sc.parent;
 4936         }
 4937 
 4938         if (cldec.errors)
 4939             cldec.type = Type.terror;
 4940         cldec.type = cldec.type.typeSemantic(cldec.loc, sc);
 4941         if (auto tc = cldec.type.isTypeClass())
 4942             if (tc.sym != cldec)
 4943             {
 4944                 auto ti = tc.sym.isInstantiated();
 4945                 if (ti && isError(ti))
 4946                     tc.sym = cldec;
 4947             }
 4948 
 4949         // Ungag errors when not speculative
 4950         Ungag ungag = cldec.ungagSpeculative();
 4951 
 4952         if (cldec.semanticRun == PASS.init)
 4953         {
 4954             cldec.protection = sc.protection;
 4955 
 4956             cldec.storage_class |= sc.stc;
 4957             if (cldec.storage_class & STC.auto_)
 4958                 cldec.error("storage class `auto` is invalid when declaring a class, did you mean to use `scope`?");
 4959             if (cldec.storage_class & STC.scope_)
 4960                 cldec.stack = true;
 4961             if (cldec.storage_class & STC.abstract_)
 4962                 cldec.isabstract = Abstract.yes;
 4963 
 4964             cldec.userAttribDecl = sc.userAttribDecl;
 4965 
 4966             if (sc.linkage == LINK.cpp)
 4967                 cldec.classKind = ClassKind.cpp;
 4968             cldec.cppnamespace = sc.namespace;
 4969             cldec.cppmangle = sc.cppmangle;
 4970             if (sc.linkage == LINK.objc)
 4971                 objc.setObjc(cldec);
 4972         }
 4973         else if (cldec.symtab && !scx)
 4974         {
 4975             return;
 4976         }
 4977         cldec.semanticRun = PASS.semantic;
 4978         UserAttributeDeclaration.checkGNUABITag(cldec, sc.linkage);
 4979 
 4980         if (cldec.baseok < Baseok.done)
 4981         {
 4982             /* https://issues.dlang.org/show_bug.cgi?id=12078
 4983              * https://issues.dlang.org/show_bug.cgi?id=12143