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