"Fossies" - the Fresh Open Source Software Archive

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


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

    1 /**
    2  * Semantic analysis of expressions.
    3  *
    4  * Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions)
    5  *
    6  * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
    7  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
    8  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
    9  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/expressionsem.d, _expressionsem.d)
   10  * Documentation:  https://dlang.org/phobos/dmd_expressionsem.html
   11  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/expressionsem.d
   12  */
   13 
   14 module dmd.expressionsem;
   15 
   16 import core.stdc.stdio;
   17 
   18 import dmd.access;
   19 import dmd.aggregate;
   20 import dmd.aliasthis;
   21 import dmd.arrayop;
   22 import dmd.arraytypes;
   23 import dmd.attrib;
   24 import dmd.astcodegen;
   25 import dmd.canthrow;
   26 import dmd.chkformat;
   27 import dmd.ctorflow;
   28 import dmd.dscope;
   29 import dmd.dsymbol;
   30 import dmd.declaration;
   31 import dmd.dclass;
   32 import dmd.dcast;
   33 import dmd.delegatize;
   34 import dmd.denum;
   35 import dmd.dimport;
   36 import dmd.dinterpret;
   37 import dmd.dmangle;
   38 import dmd.dmodule;
   39 import dmd.dstruct;
   40 import dmd.dsymbolsem;
   41 import dmd.dtemplate;
   42 import dmd.errors;
   43 import dmd.escape;
   44 import dmd.expression;
   45 import dmd.func;
   46 import dmd.globals;
   47 import dmd.hdrgen;
   48 import dmd.id;
   49 import dmd.identifier;
   50 import dmd.imphint;
   51 import dmd.init;
   52 import dmd.initsem;
   53 import dmd.inline;
   54 import dmd.intrange;
   55 import dmd.mtype;
   56 import dmd.nspace;
   57 import dmd.opover;
   58 import dmd.optimize;
   59 import dmd.parse;
   60 import dmd.root.ctfloat;
   61 import dmd.root.file;
   62 import dmd.root.filename;
   63 import dmd.root.outbuffer;
   64 import dmd.root.rootobject;
   65 import dmd.root.string;
   66 import dmd.semantic2;
   67 import dmd.semantic3;
   68 import dmd.sideeffect;
   69 import dmd.safe;
   70 import dmd.target;
   71 import dmd.tokens;
   72 import dmd.traits;
   73 import dmd.typesem;
   74 import dmd.typinf;
   75 import dmd.utf;
   76 import dmd.utils;
   77 import dmd.visitor;
   78 
   79 enum LOGSEMANTIC = false;
   80 
   81 /********************************************************
   82  * Perform semantic analysis and CTFE on expressions to produce
   83  * a string.
   84  * Params:
   85  *      buf = append generated string to buffer
   86  *      sc = context
   87  *      exps = array of Expressions
   88  * Returns:
   89  *      true on error
   90  */
   91 bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
   92 {
   93     if (!exps)
   94         return false;
   95 
   96     foreach (ex; *exps)
   97     {
   98         if (!ex)
   99             continue;
  100         auto sc2 = sc.startCTFE();
  101         auto e2 = ex.expressionSemantic(sc2);
  102         auto e3 = resolveProperties(sc2, e2);
  103         sc2.endCTFE();
  104 
  105         // allowed to contain types as well as expressions
  106         auto e4 = ctfeInterpretForPragmaMsg(e3);
  107         if (!e4 || e4.op == TOK.error)
  108             return true;
  109 
  110         // expand tuple
  111         if (auto te = e4.isTupleExp())
  112         {
  113             if (expressionsToString(buf, sc, te.exps))
  114                 return true;
  115             continue;
  116         }
  117         // char literals exp `.toStringExp` return `null` but we cant override it
  118         // because in most contexts we don't want the conversion to succeed.
  119         IntegerExp ie = e4.isIntegerExp();
  120         const ty = (ie && ie.type) ? ie.type.ty : Terror;
  121         if (ty.isSomeChar)
  122         {
  123             auto tsa = new TypeSArray(ie.type, IntegerExp.literal!1);
  124             e4 = new ArrayLiteralExp(ex.loc, tsa, ie);
  125         }
  126 
  127         if (StringExp se = e4.toStringExp())
  128             buf.writestring(se.toUTF8(sc).peekString());
  129         else
  130             buf.writestring(e4.toString());
  131     }
  132     return false;
  133 }
  134 
  135 
  136 /***********************************************************
  137  * Resolve `exp` as a compile-time known string.
  138  * Params:
  139  *  sc  = scope
  140  *  exp = Expression which expected as a string
  141  *  s   = What the string is expected for, will be used in error diagnostic.
  142  * Returns:
  143  *  String literal, or `null` if error happens.
  144  */
  145 StringExp semanticString(Scope *sc, Expression exp, const char* s)
  146 {
  147     sc = sc.startCTFE();
  148     exp = exp.expressionSemantic(sc);
  149     exp = resolveProperties(sc, exp);
  150     sc = sc.endCTFE();
  151 
  152     if (exp.op == TOK.error)
  153         return null;
  154 
  155     auto e = exp;
  156     if (exp.type.isString())
  157     {
  158         e = e.ctfeInterpret();
  159         if (e.op == TOK.error)
  160             return null;
  161     }
  162 
  163     auto se = e.toStringExp();
  164     if (!se)
  165     {
  166         exp.error("`string` expected for %s, not `(%s)` of type `%s`",
  167             s, exp.toChars(), exp.type.toChars());
  168         return null;
  169     }
  170     return se;
  171 }
  172 
  173 private Expression extractOpDollarSideEffect(Scope* sc, UnaExp ue)
  174 {
  175     Expression e0;
  176     Expression e1 = Expression.extractLast(ue.e1, e0);
  177     // https://issues.dlang.org/show_bug.cgi?id=12585
  178     // Extract the side effect part if ue.e1 is comma.
  179 
  180     if ((sc.flags & SCOPE.ctfe) ? hasSideEffect(e1) : !isTrivialExp(e1)) // match logic in extractSideEffect()
  181     {
  182         /* Even if opDollar is needed, 'e1' should be evaluate only once. So
  183          * Rewrite:
  184          *      e1.opIndex( ... use of $ ... )
  185          *      e1.opSlice( ... use of $ ... )
  186          * as:
  187          *      (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...)
  188          *      (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...)
  189          */
  190         e1 = extractSideEffect(sc, "__dop", e0, e1, false);
  191         assert(e1.op == TOK.variable);
  192         VarExp ve = cast(VarExp)e1;
  193         ve.var.storage_class |= STC.exptemp;     // lifetime limited to expression
  194     }
  195     ue.e1 = e1;
  196     return e0;
  197 }
  198 
  199 /**************************************
  200  * Runs semantic on ae.arguments. Declares temporary variables
  201  * if '$' was used.
  202  */
  203 Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
  204 {
  205     assert(!ae.lengthVar);
  206     *pe0 = null;
  207     AggregateDeclaration ad = isAggregate(ae.e1.type);
  208     Dsymbol slice = search_function(ad, Id.slice);
  209     //printf("slice = %s %s\n", slice.kind(), slice.toChars());
  210     foreach (i, e; *ae.arguments)
  211     {
  212         if (i == 0)
  213             *pe0 = extractOpDollarSideEffect(sc, ae);
  214 
  215         if (e.op == TOK.interval && !(slice && slice.isTemplateDeclaration()))
  216         {
  217         Lfallback:
  218             if (ae.arguments.dim == 1)
  219                 return null;
  220             ae.error("multi-dimensional slicing requires template `opSlice`");
  221             return ErrorExp.get();
  222         }
  223         //printf("[%d] e = %s\n", i, e.toChars());
  224 
  225         // Create scope for '$' variable for this dimension
  226         auto sym = new ArrayScopeSymbol(sc, ae);
  227         sym.parent = sc.scopesym;
  228         sc = sc.push(sym);
  229         ae.lengthVar = null; // Create it only if required
  230         ae.currentDimension = i; // Dimension for $, if required
  231 
  232         e = e.expressionSemantic(sc);
  233         e = resolveProperties(sc, e);
  234 
  235         if (ae.lengthVar && sc.func)
  236         {
  237             // If $ was used, declare it now
  238             Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
  239             de = de.expressionSemantic(sc);
  240             *pe0 = Expression.combine(*pe0, de);
  241         }
  242         sc = sc.pop();
  243 
  244         if (e.op == TOK.interval)
  245         {
  246             IntervalExp ie = cast(IntervalExp)e;
  247 
  248             auto tiargs = new Objects();
  249             Expression edim = new IntegerExp(ae.loc, i, Type.tsize_t);
  250             edim = edim.expressionSemantic(sc);
  251             tiargs.push(edim);
  252 
  253             auto fargs = new Expressions(2);
  254             (*fargs)[0] = ie.lwr;
  255             (*fargs)[1] = ie.upr;
  256 
  257             uint xerrors = global.startGagging();
  258             sc = sc.push();
  259             FuncDeclaration fslice = resolveFuncCall(ae.loc, sc, slice, tiargs, ae.e1.type, fargs, FuncResolveFlag.quiet);
  260             sc = sc.pop();
  261             global.endGagging(xerrors);
  262             if (!fslice)
  263                 goto Lfallback;
  264 
  265             e = new DotTemplateInstanceExp(ae.loc, ae.e1, slice.ident, tiargs);
  266             e = new CallExp(ae.loc, e, fargs);
  267             e = e.expressionSemantic(sc);
  268         }
  269 
  270         if (!e.type)
  271         {
  272             ae.error("`%s` has no value", e.toChars());
  273             e = ErrorExp.get();
  274         }
  275         if (e.op == TOK.error)
  276             return e;
  277 
  278         (*ae.arguments)[i] = e;
  279     }
  280     return ae;
  281 }
  282 
  283 /**************************************
  284  * Runs semantic on se.lwr and se.upr. Declares a temporary variable
  285  * if '$' was used.
  286  * Returns:
  287  *      ae, or ErrorExp if errors occurred
  288  */
  289 Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* pe0)
  290 {
  291     //assert(!ae.lengthVar);
  292     if (!ie)
  293         return ae;
  294 
  295     VarDeclaration lengthVar = ae.lengthVar;
  296     bool errors = false;
  297 
  298     // create scope for '$'
  299     auto sym = new ArrayScopeSymbol(sc, ae);
  300     sym.parent = sc.scopesym;
  301     sc = sc.push(sym);
  302 
  303     Expression sem(Expression e)
  304     {
  305         e = e.expressionSemantic(sc);
  306         e = resolveProperties(sc, e);
  307         if (!e.type)
  308         {
  309             ae.error("`%s` has no value", e.toChars());
  310             errors = true;
  311         }
  312         return e;
  313     }
  314 
  315     ie.lwr = sem(ie.lwr);
  316     ie.upr = sem(ie.upr);
  317 
  318     if (lengthVar != ae.lengthVar && sc.func)
  319     {
  320         // If $ was used, declare it now
  321         Expression de = new DeclarationExp(ae.loc, ae.lengthVar);
  322         de = de.expressionSemantic(sc);
  323         *pe0 = Expression.combine(*pe0, de);
  324     }
  325 
  326     sc = sc.pop();
  327 
  328     return errors ? ErrorExp.get() : ae;
  329 }
  330 
  331 /******************************
  332  * Perform semantic() on an array of Expressions.
  333  */
  334 bool arrayExpressionSemantic(Expressions* exps, Scope* sc, bool preserveErrors = false)
  335 {
  336     bool err = false;
  337     if (exps)
  338     {
  339         foreach (ref e; *exps)
  340         {
  341             if (e)
  342             {
  343                 auto e2 = e.expressionSemantic(sc);
  344                 if (e2.op == TOK.error)
  345                     err = true;
  346                 if (preserveErrors || e2.op != TOK.error)
  347                     e = e2;
  348             }
  349         }
  350     }
  351     return err;
  352 }
  353 
  354 /******************************
  355  * Check the tail CallExp is really property function call.
  356  * Bugs:
  357  * This doesn't appear to do anything.
  358  */
  359 private bool checkPropertyCall(Expression e)
  360 {
  361     e = lastComma(e);
  362 
  363     if (e.op == TOK.call)
  364     {
  365         CallExp ce = cast(CallExp)e;
  366         TypeFunction tf;
  367         if (ce.f)
  368         {
  369             tf = cast(TypeFunction)ce.f.type;
  370             /* If a forward reference to ce.f, try to resolve it
  371              */
  372             if (!tf.deco && ce.f.semanticRun < PASS.semanticdone)
  373             {
  374                 ce.f.dsymbolSemantic(null);
  375                 tf = cast(TypeFunction)ce.f.type;
  376             }
  377         }
  378         else if (ce.e1.type.ty == Tfunction)
  379             tf = cast(TypeFunction)ce.e1.type;
  380         else if (ce.e1.type.ty == Tdelegate)
  381             tf = cast(TypeFunction)ce.e1.type.nextOf();
  382         else if (ce.e1.type.ty == Tpointer && ce.e1.type.nextOf().ty == Tfunction)
  383             tf = cast(TypeFunction)ce.e1.type.nextOf();
  384         else
  385             assert(0);
  386     }
  387     return false;
  388 }
  389 
  390 /******************************
  391  * Find symbol in accordance with the UFCS name look up rule
  392  */
  393 private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)
  394 {
  395     //printf("searchUFCS(ident = %s)\n", ident.toChars());
  396     Loc loc = ue.loc;
  397 
  398     // TODO: merge with Scope.search.searchScopes()
  399     Dsymbol searchScopes(int flags)
  400     {
  401         Dsymbol s = null;
  402         for (Scope* scx = sc; scx; scx = scx.enclosing)
  403         {
  404             if (!scx.scopesym)
  405                 continue;
  406             if (scx.scopesym.isModule())
  407                 flags |= SearchUnqualifiedModule;    // tell Module.search() that SearchLocalsOnly is to be obeyed
  408             s = scx.scopesym.search(loc, ident, flags);
  409             if (s)
  410             {
  411                 // overload set contains only module scope symbols.
  412                 if (s.isOverloadSet())
  413                     break;
  414                 // selective/renamed imports also be picked up
  415                 if (AliasDeclaration ad = s.isAliasDeclaration())
  416                 {
  417                     if (ad._import)
  418                         break;
  419                 }
  420                 // See only module scope symbols for UFCS target.
  421                 Dsymbol p = s.toParent2();
  422                 if (p && p.isModule())
  423                     break;
  424             }
  425             s = null;
  426 
  427             // Stop when we hit a module, but keep going if that is not just under the global scope
  428             if (scx.scopesym.isModule() && !(scx.enclosing && !scx.enclosing.enclosing))
  429                 break;
  430         }
  431         return s;
  432     }
  433 
  434     int flags = 0;
  435     Dsymbol s;
  436 
  437     if (sc.flags & SCOPE.ignoresymbolvisibility)
  438         flags |= IgnoreSymbolVisibility;
  439 
  440     // First look in local scopes
  441     s = searchScopes(flags | SearchLocalsOnly);
  442     if (!s)
  443     {
  444         // Second look in imported modules
  445         s = searchScopes(flags | SearchImportsOnly);
  446     }
  447 
  448     if (!s)
  449         return ue.e1.type.Type.getProperty(sc, loc, ident, 0);
  450 
  451     FuncDeclaration f = s.isFuncDeclaration();
  452     if (f)
  453     {
  454         TemplateDeclaration td = getFuncTemplateDecl(f);
  455         if (td)
  456         {
  457             if (td.overroot)
  458                 td = td.overroot;
  459             s = td;
  460         }
  461     }
  462 
  463     if (ue.op == TOK.dotTemplateInstance)
  464     {
  465         DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)ue;
  466         auto ti = new TemplateInstance(loc, s.ident, dti.ti.tiargs);
  467         if (!ti.updateTempDecl(sc, s))
  468             return ErrorExp.get();
  469         return new ScopeExp(loc, ti);
  470     }
  471     else
  472     {
  473         //printf("-searchUFCS() %s\n", s.toChars());
  474         return new DsymbolExp(loc, s);
  475     }
  476 }
  477 
  478 /******************************
  479  * Pull out callable entity with UFCS.
  480  */
  481 private Expression resolveUFCS(Scope* sc, CallExp ce)
  482 {
  483     Loc loc = ce.loc;
  484     Expression eleft;
  485     Expression e;
  486 
  487     if (ce.e1.op == TOK.dotIdentifier)
  488     {
  489         DotIdExp die = cast(DotIdExp)ce.e1;
  490         Identifier ident = die.ident;
  491 
  492         Expression ex = die.semanticX(sc);
  493         if (ex != die)
  494         {
  495             ce.e1 = ex;
  496             return null;
  497         }
  498         eleft = die.e1;
  499 
  500         Type t = eleft.type.toBasetype();
  501         if (t.ty == Tarray || t.ty == Tsarray || t.ty == Tnull || (t.isTypeBasic() && t.ty != Tvoid))
  502         {
  503             /* Built-in types and arrays have no callable properties, so do shortcut.
  504              * It is necessary in: e.init()
  505              */
  506         }
  507         else if (t.ty == Taarray)
  508         {
  509             if (ident == Id.remove)
  510             {
  511                 /* Transform:
  512                  *  aa.remove(arg) into delete aa[arg]
  513                  */
  514                 if (!ce.arguments || ce.arguments.dim != 1)
  515                 {
  516                     ce.error("expected key as argument to `aa.remove()`");
  517                     return ErrorExp.get();
  518                 }
  519                 if (!eleft.type.isMutable())
  520                 {
  521                     ce.error("cannot remove key from `%s` associative array `%s`", MODtoChars(t.mod), eleft.toChars());
  522                     return ErrorExp.get();
  523                 }
  524                 Expression key = (*ce.arguments)[0];
  525                 key = key.expressionSemantic(sc);
  526                 key = resolveProperties(sc, key);
  527 
  528                 TypeAArray taa = cast(TypeAArray)t;
  529                 key = key.implicitCastTo(sc, taa.index);
  530 
  531                 if (key.checkValue() || key.checkSharedAccess(sc))
  532                     return ErrorExp.get();
  533 
  534                 semanticTypeInfo(sc, taa.index);
  535 
  536                 return new RemoveExp(loc, eleft, key);
  537             }
  538         }
  539         else
  540         {
  541             if (Expression ey = die.semanticY(sc, 1))
  542             {
  543                 if (ey.op == TOK.error)
  544                     return ey;
  545                 ce.e1 = ey;
  546                 if (isDotOpDispatch(ey))
  547                 {
  548                     uint errors = global.startGagging();
  549                     e = ce.syntaxCopy().expressionSemantic(sc);
  550                     if (!global.endGagging(errors))
  551                         return e;
  552 
  553                     // even opDispatch and UFCS must have valid arguments,
  554                     // so now that we've seen indication of a problem,
  555                     // check them for issues.
  556                     Expressions* originalArguments = Expression.arraySyntaxCopy(ce.arguments);
  557 
  558                     if (arrayExpressionSemantic(originalArguments, sc))
  559                         return ErrorExp.get();
  560 
  561                     /* fall down to UFCS */
  562                 }
  563                 else
  564                     return null;
  565             }
  566         }
  567 
  568         /* https://issues.dlang.org/show_bug.cgi?id=13953
  569          *
  570          * If a struct has an alias this to an associative array
  571          * and remove is used on a struct instance, we have to
  572          * check first if there is a remove function that can be called
  573          * on the struct. If not we must check the alias this.
  574          *
  575          * struct A
  576          * {
  577          *      string[string] a;
  578          *      alias a this;
  579          * }
  580          *
  581          * void fun()
  582          * {
  583          *      A s;
  584          *      s.remove("foo");
  585          * }
  586          */
  587         const errors = global.startGagging();
  588         e = searchUFCS(sc, die, ident);
  589         // if there were any errors and the identifier was remove
  590         if (global.endGagging(errors))
  591         {
  592             if (ident == Id.remove)
  593             {
  594                 // check alias this
  595                 Expression alias_e = resolveAliasThis(sc, die.e1, 1);
  596                 if (alias_e && alias_e != die.e1)
  597                 {
  598                     die.e1 = alias_e;
  599                     CallExp ce2 = cast(CallExp)ce.syntaxCopy();
  600                     ce2.e1 = die;
  601                     e = cast(CallExp)ce2.trySemantic(sc);
  602                     if (e)
  603                         return e;
  604                 }
  605             }
  606             // if alias this did not work out, print the initial errors
  607             searchUFCS(sc, die, ident);
  608         }
  609     }
  610     else if (ce.e1.op == TOK.dotTemplateInstance)
  611     {
  612         DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)ce.e1;
  613         if (Expression ey = dti.semanticY(sc, 1))
  614         {
  615             ce.e1 = ey;
  616             return null;
  617         }
  618         eleft = dti.e1;
  619         e = searchUFCS(sc, dti, dti.ti.name);
  620     }
  621     else
  622         return null;
  623 
  624     // Rewrite
  625     ce.e1 = e;
  626     if (!ce.arguments)
  627         ce.arguments = new Expressions();
  628     ce.arguments.shift(eleft);
  629 
  630     return null;
  631 }
  632 
  633 /******************************
  634  * Pull out property with UFCS.
  635  */
  636 private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 = null)
  637 {
  638     Loc loc = e1.loc;
  639     Expression eleft;
  640     Expression e;
  641 
  642     if (e1.op == TOK.dotIdentifier)
  643     {
  644         DotIdExp die = cast(DotIdExp)e1;
  645         eleft = die.e1;
  646         e = searchUFCS(sc, die, die.ident);
  647     }
  648     else if (e1.op == TOK.dotTemplateInstance)
  649     {
  650         DotTemplateInstanceExp dti;
  651         dti = cast(DotTemplateInstanceExp)e1;
  652         eleft = dti.e1;
  653         e = searchUFCS(sc, dti, dti.ti.name);
  654     }
  655     else
  656         return null;
  657 
  658     if (e is null)
  659         return null;
  660 
  661     // Rewrite
  662     if (e2)
  663     {
  664         // run semantic without gagging
  665         e2 = e2.expressionSemantic(sc);
  666 
  667         /* f(e1) = e2
  668          */
  669         Expression ex = e.copy();
  670         auto a1 = new Expressions(1);
  671         (*a1)[0] = eleft;
  672         ex = new CallExp(loc, ex, a1);
  673         auto e1PassSemantic = ex.trySemantic(sc);
  674 
  675         /* f(e1, e2)
  676          */
  677         auto a2 = new Expressions(2);
  678         (*a2)[0] = eleft;
  679         (*a2)[1] = e2;
  680         e = new CallExp(loc, e, a2);
  681         e = e.trySemantic(sc);
  682         if (!e1PassSemantic && !e)
  683         {
  684             /* https://issues.dlang.org/show_bug.cgi?id=20448
  685              *
  686              * If both versions have failed to pass semantic,
  687              * f(e1) = e2 gets priority in error printing
  688              * because f might be a templated function that
  689              * failed to instantiate and we have to print
  690              * the instantiation errors.
  691              */
  692             return e1.expressionSemantic(sc);
  693         }
  694         else if (ex && !e)
  695         {
  696             checkPropertyCall(ex);
  697             ex = new AssignExp(loc, ex, e2);
  698             return ex.expressionSemantic(sc);
  699         }
  700         else
  701         {
  702             // strict setter prints errors if fails
  703             e = e.expressionSemantic(sc);
  704         }
  705         checkPropertyCall(e);
  706         return e;
  707     }
  708     else
  709     {
  710         /* f(e1)
  711          */
  712         auto arguments = new Expressions(1);
  713         (*arguments)[0] = eleft;
  714         e = new CallExp(loc, e, arguments);
  715         e = e.expressionSemantic(sc);
  716         checkPropertyCall(e);
  717         return e.expressionSemantic(sc);
  718     }
  719 }
  720 
  721 /******************************
  722  * If e1 is a property function (template), resolve it.
  723  */
  724 Expression resolvePropertiesOnly(Scope* sc, Expression e1)
  725 {
  726     //printf("e1 = %s %s\n", Token::toChars(e1.op), e1.toChars());
  727 
  728     Expression handleOverloadSet(OverloadSet os)
  729     {
  730         assert(os);
  731         foreach (s; os.a)
  732         {
  733             auto fd = s.isFuncDeclaration();
  734             auto td = s.isTemplateDeclaration();
  735             if (fd)
  736             {
  737                 if ((cast(TypeFunction)fd.type).isproperty)
  738                     return resolveProperties(sc, e1);
  739             }
  740             else if (td && td.onemember && (fd = td.onemember.isFuncDeclaration()) !is null)
  741             {
  742                 if ((cast(TypeFunction)fd.type).isproperty ||
  743                     (fd.storage_class2 & STC.property) ||
  744                     (td._scope.stc & STC.property))
  745                     return resolveProperties(sc, e1);
  746             }
  747         }
  748         return e1;
  749     }
  750 
  751     Expression handleTemplateDecl(TemplateDeclaration td)
  752     {
  753         assert(td);
  754         if (td.onemember)
  755         {
  756             if (auto fd = td.onemember.isFuncDeclaration())
  757             {
  758                 if ((cast(TypeFunction)fd.type).isproperty ||
  759                     (fd.storage_class2 & STC.property) ||
  760                     (td._scope.stc & STC.property))
  761                     return resolveProperties(sc, e1);
  762             }
  763         }
  764         return e1;
  765     }
  766 
  767     Expression handleFuncDecl(FuncDeclaration fd)
  768     {
  769         assert(fd);
  770         if ((cast(TypeFunction)fd.type).isproperty)
  771             return resolveProperties(sc, e1);
  772         return e1;
  773     }
  774 
  775     if (auto de = e1.isDotExp())
  776     {
  777         if (auto os = de.e2.isOverExp())
  778             return handleOverloadSet(os.vars);
  779     }
  780     else if (auto oe = e1.isOverExp())
  781         return handleOverloadSet(oe.vars);
  782     else if (auto dti = e1.isDotTemplateInstanceExp())
  783     {
  784         if (dti.ti.tempdecl)
  785             if (auto td = dti.ti.tempdecl.isTemplateDeclaration())
  786                 return handleTemplateDecl(td);
  787     }
  788     else if (auto dte = e1.isDotTemplateExp())
  789         return handleTemplateDecl(dte.td);
  790     else if (e1.op == TOK.scope_)
  791     {
  792         Dsymbol s = (cast(ScopeExp)e1).sds;
  793         TemplateInstance ti = s.isTemplateInstance();
  794         if (ti && !ti.semanticRun && ti.tempdecl)
  795             if (auto td = ti.tempdecl.isTemplateDeclaration())
  796                 return handleTemplateDecl(td);
  797     }
  798     else if (e1.op == TOK.template_)
  799         return handleTemplateDecl((cast(TemplateExp)e1).td);
  800     else if (e1.op == TOK.dotVariable && e1.type.ty == Tfunction)
  801     {
  802         DotVarExp dve = cast(DotVarExp)e1;
  803         return handleFuncDecl(dve.var.isFuncDeclaration());
  804     }
  805     else if (e1.op == TOK.variable && e1.type && e1.type.ty == Tfunction && (sc.intypeof || !(cast(VarExp)e1).var.needThis()))
  806         return handleFuncDecl((cast(VarExp)e1).var.isFuncDeclaration());
  807     return e1;
  808 }
  809 
  810 /****************************************
  811  * Turn symbol `s` into the expression it represents.
  812  *
  813  * Params:
  814  *      s = symbol to resolve
  815  *      loc = location of use of `s`
  816  *      sc = context
  817  *      hasOverloads = applies if `s` represents a function.
  818  *          true means it's overloaded and will be resolved later,
  819  *          false means it's the exact function symbol.
  820  * Returns:
  821  *      `s` turned into an expression, `ErrorExp` if an error occurred
  822  */
  823 Expression symbolToExp(Dsymbol s, const ref Loc loc, Scope *sc, bool hasOverloads)
  824 {
  825     static if (LOGSEMANTIC)
  826     {
  827         printf("DsymbolExp::resolve(%s %s)\n", s.kind(), s.toChars());
  828     }
  829 
  830 Lagain:
  831     Expression e;
  832 
  833     //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
  834     //printf("s = '%s', s.kind = '%s'\n", s.toChars(), s.kind());
  835     Dsymbol olds = s;
  836     Declaration d = s.isDeclaration();
  837     if (d && (d.storage_class & STC.templateparameter))
  838     {
  839         s = s.toAlias();
  840     }
  841     else
  842     {
  843         if (!s.isFuncDeclaration()) // functions are checked after overloading
  844         {
  845             s.checkDeprecated(loc, sc);
  846             if (d)
  847                 d.checkDisabled(loc, sc);
  848         }
  849 
  850         // https://issues.dlang.org/show_bug.cgi?id=12023
  851         // if 's' is a tuple variable, the tuple is returned.
  852         s = s.toAlias();
  853 
  854         //printf("s = '%s', s.kind = '%s', s.needThis() = %p\n", s.toChars(), s.kind(), s.needThis());
  855         if (s != olds && !s.isFuncDeclaration())
  856         {
  857             s.checkDeprecated(loc, sc);
  858             if (d)
  859                 d.checkDisabled(loc, sc);
  860         }
  861     }
  862 
  863     if (auto em = s.isEnumMember())
  864     {
  865         return em.getVarExp(loc, sc);
  866     }
  867     if (auto v = s.isVarDeclaration())
  868     {
  869         //printf("Identifier '%s' is a variable, type '%s'\n", s.toChars(), v.type.toChars());
  870         if (sc.intypeof == 1 && !v.inuse)
  871             v.dsymbolSemantic(sc);
  872         if (!v.type ||                  // during variable type inference
  873             !v.type.deco && v.inuse)    // during variable type semantic
  874         {
  875             if (v.inuse)    // variable type depends on the variable itself
  876                 error(loc, "circular reference to %s `%s`", v.kind(), v.toPrettyChars());
  877             else            // variable type cannot be determined
  878                 error(loc, "forward reference to %s `%s`", v.kind(), v.toPrettyChars());
  879             return ErrorExp.get();
  880         }
  881         if (v.type.ty == Terror)
  882             return ErrorExp.get();
  883 
  884         if ((v.storage_class & STC.manifest) && v._init)
  885         {
  886             if (v.inuse)
  887             {
  888                 error(loc, "circular initialization of %s `%s`", v.kind(), v.toPrettyChars());
  889                 return ErrorExp.get();
  890             }
  891             e = v.expandInitializer(loc);
  892             v.inuse++;
  893             e = e.expressionSemantic(sc);
  894             v.inuse--;
  895             return e;
  896         }
  897 
  898         // Change the ancestor lambdas to delegate before hasThis(sc) call.
  899         if (v.checkNestedReference(sc, loc))
  900             return ErrorExp.get();
  901 
  902         if (v.needThis() && hasThis(sc))
  903             e = new DotVarExp(loc, new ThisExp(loc), v);
  904         else
  905             e = new VarExp(loc, v);
  906         e = e.expressionSemantic(sc);
  907         return e;
  908     }
  909     if (auto fld = s.isFuncLiteralDeclaration())
  910     {
  911         //printf("'%s' is a function literal\n", fld.toChars());
  912         e = new FuncExp(loc, fld);
  913         return e.expressionSemantic(sc);
  914     }
  915     if (auto f = s.isFuncDeclaration())
  916     {
  917         f = f.toAliasFunc();
  918         if (!f.functionSemantic())
  919             return ErrorExp.get();
  920 
  921         if (!hasOverloads && f.checkForwardRef(loc))
  922             return ErrorExp.get();
  923 
  924         auto fd = s.isFuncDeclaration();
  925         fd.type = f.type;
  926         return new VarExp(loc, fd, hasOverloads);
  927     }
  928     if (OverDeclaration od = s.isOverDeclaration())
  929     {
  930         e = new VarExp(loc, od, true);
  931         e.type = Type.tvoid;
  932         return e;
  933     }
  934     if (OverloadSet o = s.isOverloadSet())
  935     {
  936         //printf("'%s' is an overload set\n", o.toChars());
  937         return new OverExp(loc, o);
  938     }
  939 
  940     if (Import imp = s.isImport())
  941     {
  942         if (!imp.pkg)
  943         {
  944             .error(loc, "forward reference of import `%s`", imp.toChars());
  945             return ErrorExp.get();
  946         }
  947         auto ie = new ScopeExp(loc, imp.pkg);
  948         return ie.expressionSemantic(sc);
  949     }
  950     if (Package pkg = s.isPackage())
  951     {
  952         auto ie = new ScopeExp(loc, pkg);
  953         return ie.expressionSemantic(sc);
  954     }
  955     if (Module mod = s.isModule())
  956     {
  957         auto ie = new ScopeExp(loc, mod);
  958         return ie.expressionSemantic(sc);
  959     }
  960     if (Nspace ns = s.isNspace())
  961     {
  962         auto ie = new ScopeExp(loc, ns);
  963         return ie.expressionSemantic(sc);
  964     }
  965 
  966     if (Type t = s.getType())
  967     {
  968         return (new TypeExp(loc, t)).expressionSemantic(sc);
  969     }
  970 
  971     if (TupleDeclaration tup = s.isTupleDeclaration())
  972     {
  973         if (tup.needThis() && hasThis(sc))
  974             e = new DotVarExp(loc, new ThisExp(loc), tup);
  975         else
  976             e = new TupleExp(loc, tup);
  977         e = e.expressionSemantic(sc);
  978         return e;
  979     }
  980 
  981     if (TemplateInstance ti = s.isTemplateInstance())
  982     {
  983         ti.dsymbolSemantic(sc);
  984         if (!ti.inst || ti.errors)
  985             return ErrorExp.get();
  986         s = ti.toAlias();
  987         if (!s.isTemplateInstance())
  988             goto Lagain;
  989         e = new ScopeExp(loc, ti);
  990         e = e.expressionSemantic(sc);
  991         return e;
  992     }
  993     if (TemplateDeclaration td = s.isTemplateDeclaration())
  994     {
  995         Dsymbol p = td.toParentLocal();
  996         FuncDeclaration fdthis = hasThis(sc);
  997         AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;
  998         if (fdthis && ad && fdthis.isMemberLocal() == ad && (td._scope.stc & STC.static_) == 0)
  999         {
 1000             e = new DotTemplateExp(loc, new ThisExp(loc), td);
 1001         }
 1002         else
 1003             e = new TemplateExp(loc, td);
 1004         e = e.expressionSemantic(sc);
 1005         return e;
 1006     }
 1007 
 1008     .error(loc, "%s `%s` is not a variable", s.kind(), s.toChars());
 1009     return ErrorExp.get();
 1010 }
 1011 
 1012 /*************************************************************
 1013  * Given var, get the
 1014  * right `this` pointer if var is in an outer class, but our
 1015  * existing `this` pointer is in an inner class.
 1016  * Params:
 1017  *      loc = location to use for error messages
 1018  *      sc = context
 1019  *      ad = struct or class we need the correct `this` for
 1020  *      e1 = existing `this`
 1021  *      var = the specific member of ad we're accessing
 1022  *      flag = if true, return `null` instead of throwing an error
 1023  * Returns:
 1024  *      Expression representing the `this` for the var
 1025  */
 1026 private Expression getRightThis(const ref Loc loc, Scope* sc, AggregateDeclaration ad, Expression e1, Dsymbol var, int flag = 0)
 1027 {
 1028     //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1.toChars(), ad.toChars(), var.toChars());
 1029 L1:
 1030     Type t = e1.type.toBasetype();
 1031     //printf("e1.type = %s, var.type = %s\n", e1.type.toChars(), var.type.toChars());
 1032 
 1033     if (e1.op == TOK.objcClassReference)
 1034     {
 1035         // We already have an Objective-C class reference, just use that as 'this'.
 1036         return e1;
 1037     }
 1038     else if (ad && ad.isClassDeclaration && ad.isClassDeclaration.classKind == ClassKind.objc &&
 1039              var.isFuncDeclaration && var.isFuncDeclaration.isStatic &&
 1040              var.isFuncDeclaration.objc.selector)
 1041     {
 1042         return new ObjcClassReferenceExp(e1.loc, cast(ClassDeclaration) ad);
 1043     }
 1044 
 1045     /* Access of a member which is a template parameter in dual-scope scenario
 1046      * class A { inc(alias m)() { ++m; } } // `m` needs `this` of `B`
 1047      * class B {int m; inc() { new A().inc!m(); } }
 1048      */
 1049     if (e1.op == TOK.this_)
 1050     {
 1051         FuncDeclaration f = hasThis(sc);
 1052         if (f && f.isThis2)
 1053         {
 1054             if (f.followInstantiationContext(ad))
 1055             {
 1056                 e1 = new VarExp(loc, f.vthis);
 1057                 e1 = new PtrExp(loc, e1);
 1058                 e1 = new IndexExp(loc, e1, IntegerExp.literal!1);
 1059                 e1 = getThisSkipNestedFuncs(loc, sc, f.toParent2(), ad, e1, t, var);
 1060                 if (e1.op == TOK.error)
 1061                     return e1;
 1062                 goto L1;
 1063             }
 1064         }
 1065     }
 1066 
 1067     /* If e1 is not the 'this' pointer for ad
 1068      */
 1069     if (ad &&
 1070         !(t.ty == Tpointer && t.nextOf().ty == Tstruct && (cast(TypeStruct)t.nextOf()).sym == ad) &&
 1071         !(t.ty == Tstruct && (cast(TypeStruct)t).sym == ad))
 1072     {
 1073         ClassDeclaration cd = ad.isClassDeclaration();
 1074         ClassDeclaration tcd = t.isClassHandle();
 1075 
 1076         /* e1 is the right this if ad is a base class of e1
 1077          */
 1078         if (!cd || !tcd || !(tcd == cd || cd.isBaseOf(tcd, null)))
 1079         {
 1080             /* Only classes can be inner classes with an 'outer'
 1081              * member pointing to the enclosing class instance
 1082              */
 1083             if (tcd && tcd.isNested())
 1084             {
 1085                 /* e1 is the 'this' pointer for an inner class: tcd.
 1086                  * Rewrite it as the 'this' pointer for the outer class.
 1087                  */
 1088                 auto vthis = tcd.followInstantiationContext(ad) ? tcd.vthis2 : tcd.vthis;
 1089                 e1 = new DotVarExp(loc, e1, vthis);
 1090                 e1.type = vthis.type;
 1091                 e1.type = e1.type.addMod(t.mod);
 1092                 // Do not call ensureStaticLinkTo()
 1093                 //e1 = e1.semantic(sc);
 1094 
 1095                 // Skip up over nested functions, and get the enclosing
 1096                 // class type.
 1097                 e1 = getThisSkipNestedFuncs(loc, sc, tcd.toParentP(ad), ad, e1, t, var);
 1098                 if (e1.op == TOK.error)
 1099                     return e1;
 1100                 goto L1;
 1101             }
 1102 
 1103             /* Can't find a path from e1 to ad
 1104              */
 1105             if (flag)
 1106                 return null;
 1107             e1.error("`this` for `%s` needs to be type `%s` not type `%s`", var.toChars(), ad.toChars(), t.toChars());
 1108             return ErrorExp.get();
 1109         }
 1110     }
 1111     return e1;
 1112 }
 1113 
 1114 /***************************************
 1115  * Pull out any properties.
 1116  */
 1117 private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null)
 1118 {
 1119     //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", Token.toChars(e1.op), e1.toChars(), e2 ? e2.toChars() : null);
 1120     Loc loc = e1.loc;
 1121 
 1122     OverloadSet os;
 1123     Dsymbol s;
 1124     Objects* tiargs;
 1125     Type tthis;
 1126     if (e1.op == TOK.dot)
 1127     {
 1128         DotExp de = cast(DotExp)e1;
 1129         if (de.e2.op == TOK.overloadSet)
 1130         {
 1131             tiargs = null;
 1132             tthis = de.e1.type;
 1133             os = (cast(OverExp)de.e2).vars;
 1134             goto Los;
 1135         }
 1136     }
 1137     else if (e1.op == TOK.overloadSet)
 1138     {
 1139         tiargs = null;
 1140         tthis = null;
 1141         os = (cast(OverExp)e1).vars;
 1142     Los:
 1143         assert(os);
 1144         FuncDeclaration fd = null;
 1145         if (e2)
 1146         {
 1147             e2 = e2.expressionSemantic(sc);
 1148             if (e2.op == TOK.error)
 1149                 return ErrorExp.get();
 1150             e2 = resolveProperties(sc, e2);
 1151 
 1152             Expressions a;
 1153             a.push(e2);
 1154 
 1155             for (size_t i = 0; i < os.a.dim; i++)
 1156             {
 1157                 if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, &a, FuncResolveFlag.quiet))
 1158                 {
 1159                     if (f.errors)
 1160                         return ErrorExp.get();
 1161                     fd = f;
 1162                     assert(fd.type.ty == Tfunction);
 1163                 }
 1164             }
 1165             if (fd)
 1166             {
 1167                 Expression e = new CallExp(loc, e1, e2);
 1168                 return e.expressionSemantic(sc);
 1169             }
 1170         }
 1171         {
 1172             for (size_t i = 0; i < os.a.dim; i++)
 1173             {
 1174                 if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, null, FuncResolveFlag.quiet))
 1175                 {
 1176                     if (f.errors)
 1177                         return ErrorExp.get();
 1178                     fd = f;
 1179                     assert(fd.type.ty == Tfunction);
 1180                     TypeFunction tf = cast(TypeFunction)fd.type;
 1181                     if (!tf.isref && e2)
 1182                     {
 1183                         error(loc, "%s is not an lvalue", e1.toChars());
 1184                         return ErrorExp.get();
 1185                     }
 1186                 }
 1187             }
 1188             if (fd)
 1189             {
 1190                 Expression e = new CallExp(loc, e1);
 1191                 if (e2)
 1192                     e = new AssignExp(loc, e, e2);
 1193                 return e.expressionSemantic(sc);
 1194             }
 1195         }
 1196         if (e2)
 1197             goto Leprop;
 1198     }
 1199     else if (e1.op == TOK.dotTemplateInstance)
 1200     {
 1201         DotTemplateInstanceExp dti = cast(DotTemplateInstanceExp)e1;
 1202         if (!dti.findTempDecl(sc))
 1203             goto Leprop;
 1204         if (!dti.ti.semanticTiargs(sc))
 1205             goto Leprop;
 1206         tiargs = dti.ti.tiargs;
 1207         tthis = dti.e1.type;
 1208         if ((os = dti.ti.tempdecl.isOverloadSet()) !is null)
 1209             goto Los;
 1210         if ((s = dti.ti.tempdecl) !is null)
 1211             goto Lfd;
 1212     }
 1213     else if (e1.op == TOK.dotTemplateDeclaration)
 1214     {
 1215         DotTemplateExp dte = cast(DotTemplateExp)e1;
 1216         s = dte.td;
 1217         tiargs = null;
 1218         tthis = dte.e1.type;
 1219         goto Lfd;
 1220     }
 1221     else if (e1.op == TOK.scope_)
 1222     {
 1223         s = (cast(ScopeExp)e1).sds;
 1224         TemplateInstance ti = s.isTemplateInstance();
 1225         if (ti && !ti.semanticRun && ti.tempdecl)
 1226         {
 1227             //assert(ti.needsTypeInference(sc));
 1228             if (!ti.semanticTiargs(sc))
 1229                 goto Leprop;
 1230             tiargs = ti.tiargs;
 1231             tthis = null;
 1232             if ((os = ti.tempdecl.isOverloadSet()) !is null)
 1233                 goto Los;
 1234             if ((s = ti.tempdecl) !is null)
 1235                 goto Lfd;
 1236         }
 1237     }
 1238     else if (e1.op == TOK.template_)
 1239     {
 1240         s = (cast(TemplateExp)e1).td;
 1241         tiargs = null;
 1242         tthis = null;
 1243         goto Lfd;
 1244     }
 1245     else if (e1.op == TOK.dotVariable && e1.type && e1.type.toBasetype().ty == Tfunction)
 1246     {
 1247         DotVarExp dve = cast(DotVarExp)e1;
 1248         s = dve.var.isFuncDeclaration();
 1249         tiargs = null;
 1250         tthis = dve.e1.type;
 1251         goto Lfd;
 1252     }
 1253     else if (e1.op == TOK.variable && e1.type && e1.type.toBasetype().ty == Tfunction)
 1254     {
 1255         s = (cast(VarExp)e1).var.isFuncDeclaration();
 1256         tiargs = null;
 1257         tthis = null;
 1258     Lfd:
 1259         assert(s);
 1260         if (e2)
 1261         {
 1262             e2 = e2.expressionSemantic(sc);
 1263             if (e2.op == TOK.error)
 1264                 return ErrorExp.get();
 1265             e2 = resolveProperties(sc, e2);
 1266 
 1267             Expressions a;
 1268             a.push(e2);
 1269 
 1270             FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, FuncResolveFlag.quiet);
 1271             if (fd && fd.type)
 1272             {
 1273                 if (fd.errors)
 1274                     return ErrorExp.get();
 1275                 assert(fd.type.ty == Tfunction);
 1276                 Expression e = new CallExp(loc, e1, e2);
 1277                 return e.expressionSemantic(sc);
 1278             }
 1279         }
 1280         {
 1281             FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, null, FuncResolveFlag.quiet);
 1282             if (fd && fd.type)
 1283             {
 1284                 if (fd.errors)
 1285                     return ErrorExp.get();
 1286                 assert(fd.type.ty == Tfunction);
 1287                 TypeFunction tf = cast(TypeFunction)fd.type;
 1288                 if (!e2 || tf.isref)
 1289                 {
 1290                     Expression e = new CallExp(loc, e1);
 1291                     if (e2)
 1292                         e = new AssignExp(loc, e, e2);
 1293                     return e.expressionSemantic(sc);
 1294                 }
 1295             }
 1296         }
 1297         if (FuncDeclaration fd = s.isFuncDeclaration())
 1298         {
 1299             // Keep better diagnostic message for invalid property usage of functions
 1300             assert(fd.type.ty == Tfunction);
 1301             Expression e = new CallExp(loc, e1, e2);
 1302             return e.expressionSemantic(sc);
 1303         }
 1304         if (e2)
 1305             goto Leprop;
 1306     }
 1307     if (e1.op == TOK.variable)
 1308     {
 1309         VarExp ve = cast(VarExp)e1;
 1310         VarDeclaration v = ve.var.isVarDeclaration();
 1311         if (v && ve.checkPurity(sc, v))
 1312             return ErrorExp.get();
 1313     }
 1314     if (e2)
 1315         return null;
 1316 
 1317     if (e1.type && e1.op != TOK.type) // function type is not a property
 1318     {
 1319         /* Look for e1 being a lazy parameter; rewrite as delegate call
 1320          * only if the symbol wasn't already treated as a delegate
 1321          */
 1322         auto ve = e1.isVarExp();
 1323         if (ve && ve.var.storage_class & STC.lazy_ && !ve.delegateWasExtracted)
 1324         {
 1325                 Expression e = new CallExp(loc, e1);
 1326                 return e.expressionSemantic(sc);
 1327         }
 1328         else if (e1.op == TOK.dotVariable)
 1329         {
 1330             // Check for reading overlapped pointer field in @safe code.
 1331             if (checkUnsafeAccess(sc, e1, true, true))
 1332                 return ErrorExp.get();
 1333         }
 1334         else if (e1.op == TOK.dot)
 1335         {
 1336             e1.error("expression has no value");
 1337             return ErrorExp.get();
 1338         }
 1339         else if (e1.op == TOK.call)
 1340         {
 1341             CallExp ce = cast(CallExp)e1;
 1342             // Check for reading overlapped pointer field in @safe code.
 1343             if (checkUnsafeAccess(sc, ce.e1, true, true))
 1344                 return ErrorExp.get();
 1345         }
 1346     }
 1347 
 1348     if (!e1.type)
 1349     {
 1350         error(loc, "cannot resolve type for %s", e1.toChars());
 1351         e1 = ErrorExp.get();
 1352     }
 1353     return e1;
 1354 
 1355 Leprop:
 1356     error(loc, "not a property %s", e1.toChars());
 1357     return ErrorExp.get();
 1358 }
 1359 
 1360 extern (C++) Expression resolveProperties(Scope* sc, Expression e)
 1361 {
 1362     //printf("resolveProperties(%s)\n", e.toChars());
 1363     e = resolvePropertiesX(sc, e);
 1364     if (e.checkRightThis(sc))
 1365         return ErrorExp.get();
 1366     return e;
 1367 }
 1368 
 1369 /****************************************
 1370  * The common type is determined by applying ?: to each pair.
 1371  * Output:
 1372  *      exps[]  properties resolved, implicitly cast to common type, rewritten in place
 1373  *      *pt     if pt is not NULL, set to the common type
 1374  * Returns:
 1375  *      true    a semantic error was detected
 1376  */
 1377 private bool arrayExpressionToCommonType(Scope* sc, Expressions* exps, Type* pt)
 1378 {
 1379     /* Still have a problem with:
 1380      *  ubyte[][] = [ cast(ubyte[])"hello", [1]];
 1381      * which works if the array literal is initialized top down with the ubyte[][]
 1382      * type, but fails with this function doing bottom up typing.
 1383      */
 1384 
 1385     //printf("arrayExpressionToCommonType()\n");
 1386     scope IntegerExp integerexp = IntegerExp.literal!0;
 1387     scope CondExp condexp = new CondExp(Loc.initial, integerexp, null, null);
 1388 
 1389     Type t0 = null;
 1390     Expression e0 = null;
 1391     size_t j0 = ~0;
 1392     bool foundType;
 1393 
 1394     for (size_t i = 0; i < exps.dim; i++)
 1395     {
 1396         Expression e = (*exps)[i];
 1397         if (!e)
 1398             continue;
 1399 
 1400         e = resolveProperties(sc, e);
 1401         if (!e.type)
 1402         {
 1403             e.error("`%s` has no value", e.toChars());
 1404             t0 = Type.terror;
 1405             continue;
 1406         }
 1407         if (e.op == TOK.type)
 1408         {
 1409             foundType = true; // do not break immediately, there might be more errors
 1410             e.checkValue(); // report an error "type T has no value"
 1411             t0 = Type.terror;
 1412             continue;
 1413         }
 1414         if (e.type.ty == Tvoid)
 1415         {
 1416             // void expressions do not concur to the determination of the common
 1417             // type.
 1418             continue;
 1419         }
 1420         if (checkNonAssignmentArrayOp(e))
 1421         {
 1422             t0 = Type.terror;
 1423             continue;
 1424         }
 1425 
 1426         e = doCopyOrMove(sc, e);
 1427 
 1428         if (!foundType && t0 && !t0.equals(e.type))
 1429         {
 1430             /* This applies ?: to merge the types. It's backwards;
 1431              * ?: should call this function to merge types.
 1432              */
 1433             condexp.type = null;
 1434             condexp.e1 = e0;
 1435             condexp.e2 = e;
 1436             condexp.loc = e.loc;
 1437             Expression ex = condexp.expressionSemantic(sc);
 1438             if (ex.op == TOK.error)
 1439                 e = ex;
 1440             else if (e.op == TOK.function_ || e.op == TOK.delegate_)
 1441             {
 1442                 // https://issues.dlang.org/show_bug.cgi?id=21285
 1443                 // Functions and delegates don't convert correctly with castTo below
 1444                 (*exps)[j0] = condexp.e1;
 1445                 e = condexp.e2;
 1446             }
 1447             else
 1448             {
 1449                 // Convert to common type
 1450                 (*exps)[j0] = condexp.e1.castTo(sc, condexp.type);
 1451                 e = condexp.e2.castTo(sc, condexp.type);
 1452             }
 1453         }
 1454         j0 = i;
 1455         e0 = e;
 1456         t0 = e.type;
 1457         if (e.op != TOK.error)
 1458             (*exps)[i] = e;
 1459     }
 1460 
 1461     if (!t0)
 1462         t0 = Type.tvoid; // [] is typed as void[]
 1463     else if (t0.ty != Terror)
 1464     {
 1465         for (size_t i = 0; i < exps.dim; i++)
 1466         {
 1467             Expression e = (*exps)[i];
 1468             if (!e)
 1469                 continue;
 1470 
 1471             e = e.implicitCastTo(sc, t0);
 1472             //assert(e.op != TOK.error);
 1473             if (e.op == TOK.error)
 1474             {
 1475                 /* https://issues.dlang.org/show_bug.cgi?id=13024
 1476                  * a workaround for the bug in typeMerge -
 1477                  * it should paint e1 and e2 by deduced common type,
 1478                  * but doesn't in this particular case.
 1479                  */
 1480                 t0 = Type.terror;
 1481                 break;
 1482             }
 1483             (*exps)[i] = e;
 1484         }
 1485     }
 1486     if (pt)
 1487         *pt = t0;
 1488 
 1489     return (t0 == Type.terror);
 1490 }
 1491 
 1492 private Expression opAssignToOp(const ref Loc loc, TOK op, Expression e1, Expression e2)
 1493 {
 1494     Expression e;
 1495     switch (op)
 1496     {
 1497     case TOK.addAssign:
 1498         e = new AddExp(loc, e1, e2);
 1499         break;
 1500 
 1501     case TOK.minAssign:
 1502         e = new MinExp(loc, e1, e2);
 1503         break;
 1504 
 1505     case TOK.mulAssign:
 1506         e = new MulExp(loc, e1, e2);
 1507         break;
 1508 
 1509     case TOK.divAssign:
 1510         e = new DivExp(loc, e1, e2);
 1511         break;
 1512 
 1513     case TOK.modAssign:
 1514         e = new ModExp(loc, e1, e2);
 1515         break;
 1516 
 1517     case TOK.andAssign:
 1518         e = new AndExp(loc, e1, e2);
 1519         break;
 1520 
 1521     case TOK.orAssign:
 1522         e = new OrExp(loc, e1, e2);
 1523         break;
 1524 
 1525     case TOK.xorAssign:
 1526         e = new XorExp(loc, e1, e2);
 1527         break;
 1528 
 1529     case TOK.leftShiftAssign:
 1530         e = new ShlExp(loc, e1, e2);
 1531         break;
 1532 
 1533     case TOK.rightShiftAssign:
 1534         e = new ShrExp(loc, e1, e2);
 1535         break;
 1536 
 1537     case TOK.unsignedRightShiftAssign:
 1538         e = new UshrExp(loc, e1, e2);
 1539         break;
 1540 
 1541     default:
 1542         assert(0);
 1543     }
 1544     return e;
 1545 }
 1546 
 1547 /*********************
 1548  * Rewrite:
 1549  *    array.length op= e2
 1550  * as:
 1551  *    array.length = array.length op e2
 1552  * or:
 1553  *    auto tmp = &array;
 1554  *    (*tmp).length = (*tmp).length op e2
 1555  */
 1556 private Expression rewriteOpAssign(BinExp exp)
 1557 {
 1558     Expression e;
 1559 
 1560     assert(exp.e1.op == TOK.arrayLength);
 1561     ArrayLengthExp ale = cast(ArrayLengthExp)exp.e1;
 1562     if (ale.e1.op == TOK.variable)
 1563     {
 1564         e = opAssignToOp(exp.loc, exp.op, ale, exp.e2);
 1565         e = new AssignExp(exp.loc, ale.syntaxCopy(), e);
 1566     }
 1567     else
 1568     {
 1569         /*    auto tmp = &array;
 1570          *    (*tmp).length = (*tmp).length op e2
 1571          */
 1572         auto tmp = copyToTemp(0, "__arraylength", new AddrExp(ale.loc, ale.e1));
 1573 
 1574         Expression e1 = new ArrayLengthExp(ale.loc, new PtrExp(ale.loc, new VarExp(ale.loc, tmp)));
 1575         Expression elvalue = e1.syntaxCopy();
 1576         e = opAssignToOp(exp.loc, exp.op, e1, exp.e2);
 1577         e = new AssignExp(exp.loc, elvalue, e);
 1578         e = new CommaExp(exp.loc, new DeclarationExp(ale.loc, tmp), e);
 1579     }
 1580     return e;
 1581 }
 1582 
 1583 /****************************************
 1584  * Preprocess arguments to function.
 1585  * Input:
 1586  *      reportErrors    whether or not to report errors here.  Some callers are not
 1587  *                      checking actual function params, so they'll do their own error reporting
 1588  * Output:
 1589  *      exps[]  tuples expanded, properties resolved, rewritten in place
 1590  * Returns:
 1591  *      true    a semantic error occurred
 1592  */
 1593 private bool preFunctionParameters(Scope* sc, Expressions* exps, const bool reportErrors = true)
 1594 {
 1595     bool err = false;
 1596     if (exps)
 1597     {
 1598         expandTuples(exps);
 1599 
 1600         for (size_t i = 0; i < exps.dim; i++)
 1601         {
 1602             Expression arg = (*exps)[i];
 1603             arg = resolveProperties(sc, arg);
 1604             if (arg.op == TOK.type)
 1605             {
 1606                 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
 1607                 arg = resolveAliasThis(sc, arg);
 1608 
 1609                 if (arg.op == TOK.type)
 1610                 {
 1611                     if (reportErrors)
 1612                     {
 1613                         arg.error("cannot pass type `%s` as a function argument", arg.toChars());
 1614                         arg = ErrorExp.get();
 1615                     }
 1616                     err = true;
 1617                 }
 1618             }
 1619             else if (arg.type.toBasetype().ty == Tfunction)
 1620             {
 1621                 if (reportErrors)
 1622                 {
 1623                     arg.error("cannot pass function `%s` as a function argument", arg.toChars());
 1624                     arg = ErrorExp.get();
 1625                 }
 1626                 err = true;
 1627             }
 1628             else if (checkNonAssignmentArrayOp(arg))
 1629             {
 1630                 arg = ErrorExp.get();
 1631                 err = true;
 1632             }
 1633             (*exps)[i] = arg;
 1634         }
 1635     }
 1636     return err;
 1637 }
 1638 
 1639 /********************************************
 1640  * Issue an error if default construction is disabled for type t.
 1641  * Default construction is required for arrays and 'out' parameters.
 1642  * Returns:
 1643  *      true    an error was issued
 1644  */
 1645 private bool checkDefCtor(Loc loc, Type t)
 1646 {
 1647     t = t.baseElemOf();
 1648     if (t.ty == Tstruct)
 1649     {
 1650         StructDeclaration sd = (cast(TypeStruct)t).sym;
 1651         if (sd.noDefaultCtor)
 1652         {
 1653             sd.error(loc, "default construction is disabled");
 1654             return true;
 1655         }
 1656     }
 1657     return false;
 1658 }
 1659 
 1660 /****************************************
 1661  * Now that we know the exact type of the function we're calling,
 1662  * the arguments[] need to be adjusted:
 1663  *      1. implicitly convert argument to the corresponding parameter type
 1664  *      2. add default arguments for any missing arguments
 1665  *      3. do default promotions on arguments corresponding to ...
 1666  *      4. add hidden _arguments[] argument
 1667  *      5. call copy constructor for struct value arguments
 1668  * Params:
 1669  *      loc       = location of function call
 1670  *      sc        = context
 1671  *      tf        = type of the function
 1672  *      ethis     = `this` argument, `null` if none or not known
 1673  *      tthis     = type of `this` argument, `null` if no `this` argument
 1674  *      arguments = array of actual arguments to function call
 1675  *      fd        = the function being called, `null` if called indirectly
 1676  *      prettype  = set to return type of function
 1677  *      peprefix  = set to expression to execute before `arguments[]` are evaluated, `null` if none
 1678  * Returns:
 1679  *      true    errors happened
 1680  */
 1681 private bool functionParameters(const ref Loc loc, Scope* sc,
 1682     TypeFunction tf, Expression ethis, Type tthis, Expressions* arguments, FuncDeclaration fd,
 1683     Type* prettype, Expression* peprefix)
 1684 {
 1685     //printf("functionParameters() %s\n", fd ? fd.toChars() : "");
 1686     assert(arguments);
 1687     assert(fd || tf.next);
 1688     size_t nargs = arguments ? arguments.dim : 0;
 1689     const size_t nparams = tf.parameterList.length;
 1690     const olderrors = global.errors;
 1691     bool err = false;
 1692     *prettype = Type.terror;
 1693     Expression eprefix = null;
 1694     *peprefix = null;
 1695 
 1696     if (nargs > nparams && tf.parameterList.varargs == VarArg.none)
 1697     {
 1698         error(loc, "expected %llu arguments, not %llu for non-variadic function type `%s`", cast(ulong)nparams, cast(ulong)nargs, tf.toChars());
 1699         return true;
 1700     }
 1701 
 1702     // If inferring return type, and semantic3() needs to be run if not already run
 1703     if (!tf.next && fd.inferRetType)
 1704     {
 1705         fd.functionSemantic();
 1706     }
 1707     else if (fd && fd.parent)
 1708     {
 1709         TemplateInstance ti = fd.parent.isTemplateInstance();
 1710         if (ti && ti.tempdecl)
 1711         {
 1712             fd.functionSemantic3();
 1713         }
 1714     }
 1715 
 1716     /* If calling a pragma(inline, true) function,
 1717      * set flag to later scan for inlines.
 1718      */
 1719     if (fd && fd.inlining == PINLINE.always)
 1720     {
 1721         if (sc._module)
 1722             sc._module.hasAlwaysInlines = true;
 1723         if (sc.func)
 1724             sc.func.hasAlwaysInlines = true;
 1725     }
 1726 
 1727     const isCtorCall = fd && fd.needThis() && fd.isCtorDeclaration();
 1728 
 1729     const size_t n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
 1730 
 1731     /* If the function return type has wildcards in it, we'll need to figure out the actual type
 1732      * based on the actual argument types.
 1733      * Start with the `this` argument, later on merge into wildmatch the mod bits of the rest
 1734      * of the arguments.
 1735      */
 1736     MOD wildmatch = (tthis && !isCtorCall) ? tthis.Type.deduceWild(tf, false) : 0;
 1737 
 1738     bool done = false;
 1739     foreach (const i; 0 .. n)
 1740     {
 1741         Expression arg = (i < nargs) ? (*arguments)[i] : null;
 1742 
 1743         if (i < nparams)
 1744         {
 1745             bool errorArgs()
 1746             {
 1747                 error(loc, "expected %llu function arguments, not %llu", cast(ulong)nparams, cast(ulong)nargs);
 1748                 return true;
 1749             }
 1750 
 1751             Parameter p = tf.parameterList[i];
 1752             const bool isRef = p.isReference();
 1753 
 1754             if (!arg)
 1755             {
 1756                 if (!p.defaultArg)
 1757                 {
 1758                     if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams)
 1759                         goto L2;
 1760                     return errorArgs();
 1761                 }
 1762                 arg = p.defaultArg;
 1763                 arg = inlineCopy(arg, sc);
 1764                 // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__
 1765                 arg = arg.resolveLoc(loc, sc);
 1766                 arguments.push(arg);
 1767                 nargs++;
 1768             }
 1769             else
 1770             {
 1771                 if (isDefaultInitOp(arg.op))
 1772                 {
 1773                     arg = arg.resolveLoc(loc, sc);
 1774                     (*arguments)[i] = arg;
 1775                 }
 1776             }
 1777 
 1778 
 1779             if (isRef && !p.type.isConst && !p.type.isImmutable
 1780                 && (p.storageClass & STC.const_) != STC.const_
 1781                 && (p.storageClass & STC.immutable_) != STC.immutable_
 1782                 && checkIfIsStructLiteralDotExpr(arg))
 1783                     break;
 1784 
 1785             if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic
 1786             {
 1787                 //printf("\t\tvarargs == 2, p.type = '%s'\n", p.type.toChars());
 1788                 {
 1789                     MATCH m;
 1790                     if ((m = arg.implicitConvTo(p.type)) > MATCH.nomatch)
 1791                     {
 1792                         if (p.type.nextOf() && arg.implicitConvTo(p.type.nextOf()) >= m)
 1793                             goto L2;
 1794                         else if (nargs != nparams)
 1795                             return errorArgs();
 1796                         goto L1;
 1797                     }
 1798                 }
 1799             L2:
 1800                 Type tb = p.type.toBasetype();
 1801                 switch (tb.ty)
 1802                 {
 1803                 case Tsarray:
 1804                 case Tarray:
 1805                     {
 1806                         /* Create a static array variable v of type arg.type:
 1807                          *  T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];
 1808                          *
 1809                          * The array literal in the initializer of the hidden variable
 1810                          * is now optimized.
 1811                          * https://issues.dlang.org/show_bug.cgi?id=2356
 1812                          */
 1813                         Type tbn = (cast(TypeArray)tb).next;    // array element type
 1814                         Type tret = p.isLazyArray();
 1815 
 1816                         auto elements = new Expressions(nargs - i);
 1817                         foreach (u; 0 .. elements.dim)
 1818                         {
 1819                             Expression a = (*arguments)[i + u];
 1820                             if (tret && a.implicitConvTo(tret))
 1821                             {
 1822                                 // p is a lazy array of delegates, tret is return type of the delegates
 1823                                 a = a.implicitCastTo(sc, tret)
 1824                                      .optimize(WANTvalue)
 1825                                      .toDelegate(tret, sc);
 1826                             }
 1827                             else
 1828                                 a = a.implicitCastTo(sc, tbn);
 1829                             a = a.addDtorHook(sc);
 1830                             (*elements)[u] = a;
 1831                         }
 1832                         // https://issues.dlang.org/show_bug.cgi?id=14395
 1833                         // Convert to a static array literal, or its slice.
 1834                         arg = new ArrayLiteralExp(loc, tbn.sarrayOf(nargs - i), elements);
 1835                         if (tb.ty == Tarray)
 1836                         {
 1837                             arg = new SliceExp(loc, arg, null, null);
 1838                             arg.type = p.type;
 1839                         }
 1840                         break;
 1841                     }
 1842                 case Tclass:
 1843                     {
 1844                         /* Set arg to be:
 1845                          *      new Tclass(arg0, arg1, ..., argn)
 1846                          */
 1847                         auto args = new Expressions(nargs - i);
 1848                         foreach (u; i .. nargs)
 1849                             (*args)[u - i] = (*arguments)[u];
 1850                         arg = new NewExp(loc, null, null, p.type, args);
 1851                         break;
 1852                     }
 1853                 default:
 1854                     if (!arg)
 1855                     {
 1856                         error(loc, "not enough arguments");
 1857                         return true;
 1858                     }
 1859                     break;
 1860                 }
 1861                 arg = arg.expressionSemantic(sc);
 1862                 //printf("\targ = '%s'\n", arg.toChars());
 1863                 arguments.setDim(i + 1);
 1864                 (*arguments)[i] = arg;
 1865                 nargs = i + 1;
 1866                 done = true;
 1867             }
 1868 
 1869         L1:
 1870             if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))
 1871             {
 1872 
 1873                 if (ubyte wm = arg.type.deduceWild(p.type, isRef))
 1874                 {
 1875                     wildmatch = wildmatch ? MODmerge(wildmatch, wm) : wm;
 1876                     //printf("[%d] p = %s, a = %s, wm = %d, wildmatch = %d\n", i, p.type.toChars(), arg.type.toChars(), wm, wildmatch);
 1877                 }
 1878             }
 1879         }
 1880         if (done)
 1881             break;
 1882     }
 1883     if ((wildmatch == MODFlags.mutable || wildmatch == MODFlags.immutable_) &&
 1884         tf.next && tf.next.hasWild() &&
 1885         (tf.isref || !tf.next.implicitConvTo(tf.next.immutableOf())))
 1886     {
 1887         bool errorInout(MOD wildmatch)
 1888         {
 1889             const(char)* s = wildmatch == MODFlags.mutable ? "mutable" : MODtoChars(wildmatch);
 1890             error(loc, "modify `inout` to `%s` is not allowed inside `inout` function", s);
 1891             return true;
 1892         }
 1893 
 1894         if (fd)
 1895         {
 1896             /* If the called function may return the reference to
 1897              * outer inout data, it should be rejected.
 1898              *
 1899              * void foo(ref inout(int) x) {
 1900              *   ref inout(int) bar(inout(int)) { return x; }
 1901              *   struct S {
 1902              *      ref inout(int) bar() inout { return x; }
 1903              *      ref inout(int) baz(alias a)() inout { return x; }
 1904              *   }
 1905              *   bar(int.init) = 1;  // bad!
 1906              *   S().bar() = 1;      // bad!
 1907              * }
 1908              * void test() {
 1909              *   int a;
 1910              *   auto s = foo(a);
 1911              *   s.baz!a() = 1;      // bad!
 1912              * }
 1913              *
 1914              */
 1915             bool checkEnclosingWild(Dsymbol s)
 1916             {
 1917                 bool checkWild(Dsymbol s)
 1918                 {
 1919                     if (!s)
 1920                         return false;
 1921                     if (auto ad = s.isAggregateDeclaration())
 1922                     {
 1923                         if (ad.isNested())
 1924                             return checkEnclosingWild(s);
 1925                     }
 1926                     else if (auto ff = s.isFuncDeclaration())
 1927                     {
 1928                         if ((cast(TypeFunction)ff.type).iswild)
 1929                             return errorInout(wildmatch);
 1930 
 1931                         if (ff.isNested() || ff.isThis())
 1932                             return checkEnclosingWild(s);
 1933                     }
 1934                     return false;
 1935                 }
 1936 
 1937                 Dsymbol ctx0 = s.toParent2();
 1938                 Dsymbol ctx1 = s.toParentLocal();
 1939                 if (checkWild(ctx0))
 1940                     return true;
 1941                 if (ctx0 != ctx1)
 1942                     return checkWild(ctx1);
 1943                 return false;
 1944             }
 1945             if ((fd.isThis() || fd.isNested()) && checkEnclosingWild(fd))
 1946                 return true;
 1947         }
 1948         else if (tf.isWild())
 1949             return errorInout(wildmatch);
 1950     }
 1951 
 1952     Expression firstArg = ((tf.next && tf.next.ty == Tvoid || isCtorCall) &&
 1953                            tthis &&
 1954                            tthis.isMutable() && tthis.toBasetype().ty == Tstruct &&
 1955                            tthis.hasPointers())
 1956                           ? ethis : null;
 1957 
 1958     assert(nargs >= nparams);
 1959     foreach (const i, arg; (*arguments)[0 .. nargs])
 1960     {
 1961         assert(arg);
 1962         if (i < nparams)
 1963         {
 1964             Parameter p = tf.parameterList[i];
 1965             Type targ = arg.type;               // keep original type for isCopyable() because alias this
 1966                                                 // resolution may hide an uncopyable type
 1967 
 1968             if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))
 1969             {
 1970                 Type tprm = p.type.hasWild()
 1971                     ? p.type.substWildTo(wildmatch)
 1972                     : p.type;
 1973 
 1974                 const hasCopyCtor = (arg.type.ty == Tstruct) && (cast(TypeStruct)arg.type).sym.hasCopyCtor;
 1975                 const typesMatch = arg.type.mutableOf().unSharedOf().equals(tprm.mutableOf().unSharedOf());
 1976                 if (!((hasCopyCtor && typesMatch) || tprm.equals(arg.type)))
 1977                 {
 1978                     //printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars());
 1979                     arg = arg.implicitCastTo(sc, tprm);
 1980                     arg = arg.optimize(WANTvalue, p.isReference());
 1981                 }
 1982             }
 1983 
 1984             // Support passing rvalue to `in` parameters
 1985             if ((p.storageClass & (STC.in_ | STC.ref_)) == (STC.in_ | STC.ref_))
 1986             {
 1987                 if (!arg.isLvalue())
 1988                 {
 1989                     auto v = copyToTemp(STC.exptemp, "__rvalue", arg);
 1990                     Expression ev = new DeclarationExp(arg.loc, v);
 1991                     ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
 1992                     arg = ev.expressionSemantic(sc);
 1993                 }
 1994                 arg = arg.toLvalue(sc, arg);
 1995 
 1996                 // Look for mutable misaligned pointer, etc., in @safe mode
 1997                 err |= checkUnsafeAccess(sc, arg, false, true);
 1998             }
 1999             else if (p.storageClass & STC.ref_)
 2000             {
 2001                 if (global.params.rvalueRefParam &&
 2002                     !arg.isLvalue() &&
 2003                     targ.isCopyable())
 2004                 {   /* allow rvalues to be passed to ref parameters by copying
 2005                      * them to a temp, then pass the temp as the argument
 2006                      */
 2007                     auto v = copyToTemp(0, "__rvalue", arg);
 2008                     Expression ev = new DeclarationExp(arg.loc, v);
 2009                     ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v));
 2010                     arg = ev.expressionSemantic(sc);
 2011                 }
 2012                 arg = arg.toLvalue(sc, arg);
 2013 
 2014                 // Look for mutable misaligned pointer, etc., in @safe mode
 2015                 err |= checkUnsafeAccess(sc, arg, false, true);
 2016             }
 2017             else if (p.storageClass & STC.out_)
 2018             {
 2019                 Type t = arg.type;
 2020                 if (!t.isMutable() || !t.isAssignable()) // check blit assignable
 2021                 {
 2022                     arg.error("cannot modify struct `%s` with immutable members", arg.toChars());
 2023                     err = true;
 2024                 }
 2025                 else
 2026                 {
 2027                     // Look for misaligned pointer, etc., in @safe mode
 2028                     err |= checkUnsafeAccess(sc, arg, false, true);
 2029                     err |= checkDefCtor(arg.loc, t); // t must be default constructible
 2030                 }
 2031                 arg = arg.toLvalue(sc, arg);
 2032             }
 2033             else if (p.storageClass & STC.lazy_)
 2034             {
 2035                 // Convert lazy argument to a delegate
 2036                 auto t = (p.type.ty == Tvoid) ? p.type : arg.type;
 2037                 arg = toDelegate(arg, t, sc);
 2038             }
 2039             //printf("arg: %s\n", arg.toChars());
 2040             //printf("type: %s\n", arg.type.toChars());
 2041             //printf("param: %s\n", p.toChars());
 2042 
 2043             if (firstArg && p.storageClass & STC.return_)
 2044             {
 2045                 /* Argument value can be assigned to firstArg.
 2046                  * Check arg to see if it matters.
 2047                  */
 2048                 if (global.params.vsafe)
 2049                     err |= checkParamArgumentReturn(sc, firstArg, arg, false);
 2050             }
 2051             else if (tf.parameterEscapes(tthis, p))
 2052             {
 2053                 /* Argument value can escape from the called function.
 2054                  * Check arg to see if it matters.
 2055                  */
 2056                 if (global.params.vsafe)
 2057                     err |= checkParamArgumentEscape(sc, fd, p, arg, false, false);
 2058             }
 2059             else
 2060             {
 2061                 /* Argument value cannot escape from the called function.
 2062                  */
 2063                 Expression a = arg;
 2064                 if (a.op == TOK.cast_)
 2065                     a = (cast(CastExp)a).e1;
 2066 
 2067                 ArrayLiteralExp ale;
 2068                 if (p.type.toBasetype().ty == Tarray && !(p.storageClass & STC.return_) &&
 2069                     (ale = a.isArrayLiteralExp()) !is null)
 2070                 {
 2071                     // allocate the array literal as temporary static array on the stack
 2072                     ale.type = ale.type.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0);
 2073                     auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale);
 2074                     auto declareTmp = new DeclarationExp(ale.loc, tmp);
 2075                     auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), p.type);
 2076                     arg = CommaExp.combine(declareTmp, castToSlice);
 2077                     arg = arg.expressionSemantic(sc);
 2078                 }
 2079                 else if (a.op == TOK.function_)
 2080                 {
 2081                     /* Function literals can only appear once, so if this
 2082                      * appearance was scoped, there cannot be any others.
 2083                      */
 2084                     FuncExp fe = cast(FuncExp)a;
 2085                     fe.fd.tookAddressOf = 0;
 2086                 }
 2087                 else if (a.op == TOK.delegate_)
 2088                 {
 2089                     /* For passing a delegate to a scoped parameter,
 2090                      * this doesn't count as taking the address of it.
 2091                      * We only worry about 'escaping' references to the function.
 2092                      */
 2093                     DelegateExp de = cast(DelegateExp)a;
 2094                     if (de.e1.op == TOK.variable)
 2095                     {
 2096                         VarExp ve = cast(VarExp)de.e1;
 2097                         FuncDeclaration f = ve.var.isFuncDeclaration();
 2098                         if (f)
 2099                         {
 2100                             if (f.tookAddressOf)
 2101                                 --f.tookAddressOf;
 2102                             //printf("--tookAddressOf = %d\n", f.tookAddressOf);
 2103                         }
 2104                     }
 2105                 }
 2106             }
 2107             if (!p.isReference())
 2108                 err |= arg.checkSharedAccess(sc);
 2109 
 2110             arg = arg.optimize(WANTvalue, p.isReference());
 2111 
 2112             /* Determine if this parameter is the "first reference" parameter through which
 2113              * later "return" arguments can be stored.
 2114              */
 2115             if (i == 0 && !tthis && p.isReference() && p.type &&
 2116                 (tf.next && tf.next.ty == Tvoid || isCtorCall))
 2117             {
 2118                 Type tb = p.type.baseElemOf();
 2119                 if (tb.isMutable() && tb.hasPointers())
 2120                 {
 2121                     firstArg = arg;
 2122                 }
 2123             }
 2124         }
 2125         else
 2126         {
 2127             // These will be the trailing ... arguments
 2128             // If not D linkage, do promotions
 2129             if (tf.linkage != LINK.d)
 2130             {
 2131                 // Promote bytes, words, etc., to ints
 2132                 arg = integralPromotions(arg, sc);
 2133 
 2134                 // Promote floats to doubles
 2135                 switch (arg.type.ty)
 2136                 {
 2137                 case Tfloat32:
 2138                     arg = arg.castTo(sc, Type.tfloat64);
 2139                     break;
 2140 
 2141                 case Timaginary32:
 2142                     arg = arg.castTo(sc, Type.timaginary64);
 2143                     break;
 2144 
 2145                 default:
 2146                     break;
 2147                 }
 2148                 if (tf.parameterList.varargs == VarArg.variadic)
 2149                 {
 2150                     const(char)* p = tf.linkage == LINK.c ? "extern(C)" : "extern(C++)";
 2151                     if (arg.type.ty == Tarray)
 2152                     {
 2153                         arg.error("cannot pass dynamic arrays to `%s` vararg functions", p);
 2154                         err = true;
 2155                     }
 2156                     if (arg.type.ty == Tsarray)
 2157                     {
 2158                         arg.error("cannot pass static arrays to `%s` vararg functions", p);
 2159                         err = true;
 2160                     }
 2161                 }
 2162             }
 2163 
 2164             // Do not allow types that need destructors or copy constructors.
 2165             if (arg.type.needsDestruction())
 2166             {
 2167                 arg.error("cannot pass types that need destruction as variadic arguments");
 2168                 err = true;
 2169             }
 2170             if (arg.type.needsCopyOrPostblit())
 2171             {
 2172                 arg.error("cannot pass types with postblits or copy constructors as variadic arguments");
 2173                 err = true;
 2174             }
 2175 
 2176             // Convert static arrays to dynamic arrays
 2177             // BUG: I don't think this is right for D2
 2178             Type tb = arg.type.toBasetype();
 2179             if (tb.ty == Tsarray)
 2180             {
 2181                 TypeSArray ts = cast(TypeSArray)tb;
 2182                 Type ta = ts.next.arrayOf();
 2183                 if (ts.size(arg.loc) == 0)
 2184                     arg = new NullExp(arg.loc, ta);
 2185                 else
 2186                     arg = arg.castTo(sc, ta);
 2187             }
 2188             if (tb.ty == Tstruct)
 2189             {
 2190                 //arg = callCpCtor(sc, arg);
 2191             }
 2192             // Give error for overloaded function addresses
 2193             if (arg.op == TOK.symbolOffset)
 2194             {
 2195                 SymOffExp se = cast(SymOffExp)arg;
 2196                 if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique())
 2197                 {
 2198                     arg.error("function `%s` is overloaded", arg.toChars());
 2199                     err = true;
 2200                 }
 2201             }
 2202             err |= arg.checkValue();
 2203             err |= arg.checkSharedAccess(sc);
 2204             arg = arg.optimize(WANTvalue);
 2205         }
 2206         (*arguments)[i] = arg;
 2207     }
 2208 
 2209     /* If calling C scanf(), printf(), or any variants, check the format string against the arguments
 2210      */
 2211     const isVa_list = tf.parameterList.varargs == VarArg.none;
 2212     if (fd && fd.flags & FUNCFLAG.printf)
 2213     {
 2214         if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
 2215         {
 2216             checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
 2217         }
 2218     }
 2219     else if (fd && fd.flags & FUNCFLAG.scanf)
 2220     {
 2221         if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
 2222         {
 2223             checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
 2224         }
 2225     }
 2226     else
 2227     {
 2228         // TODO: not checking the "v" functions yet (for those, check format string only, not args)
 2229     }
 2230 
 2231     /* Remaining problems:
 2232      * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is
 2233      *    implemented by calling a function) we'll defer this for now.
 2234      * 2. value structs (or static arrays of them) that need to be copy constructed
 2235      * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the
 2236      *    function gets called (functions normally destroy their parameters)
 2237      * 2 and 3 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned
 2238      * up properly. Pushing arguments on the stack then cannot fail.
 2239      */
 2240     {
 2241         /* TODO: tackle problem 1)
 2242          */
 2243         const bool leftToRight = true; // TODO: Any cases that need rightToLeft?
 2244         if (!leftToRight)
 2245             assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity
 2246 
 2247         const ptrdiff_t start = (leftToRight ? 0 : cast(ptrdiff_t)nargs - 1);
 2248         const ptrdiff_t end = (leftToRight ? cast(ptrdiff_t)nargs : -1);
 2249         const ptrdiff_t step = (leftToRight ? 1 : -1);
 2250 
 2251         /* Compute indices of last throwing argument and first arg needing destruction.
 2252          * Used to not set up destructors unless an arg needs destruction on a throw
 2253          * in a later argument.
 2254          */
 2255         ptrdiff_t lastthrow = -1;
 2256         ptrdiff_t firstdtor = -1;
 2257         for (ptrdiff_t i = start; i != end; i += step)
 2258         {
 2259             Expression arg = (*arguments)[i];
 2260             if (canThrow(arg, sc.func, false))
 2261                 lastthrow = i;
 2262             if (firstdtor == -1 && arg.type.needsDestruction())
 2263             {
 2264                 Parameter p = (i >= nparams ? null : tf.parameterList[i]);
 2265                 if (!(p && (p.storageClass & (STC.lazy_ | STC.ref_ | STC.out_))))
 2266                     firstdtor = i;
 2267             }
 2268         }
 2269 
 2270         /* Does problem 3) apply to this call?
 2271          */
 2272         const bool needsPrefix = (firstdtor >= 0 && lastthrow >= 0
 2273             && (lastthrow - firstdtor) * step > 0);
 2274 
 2275         /* If so, initialize 'eprefix' by declaring the gate
 2276          */
 2277         VarDeclaration gate = null;
 2278         if (needsPrefix)
 2279         {
 2280             // eprefix => bool __gate [= false]
 2281             Identifier idtmp = Identifier.generateId("__gate");
 2282             gate = new VarDeclaration(loc, Type.tbool, idtmp, null);
 2283             gate.storage_class |= STC.temp | STC.ctfe | STC.volatile_;
 2284             gate.dsymbolSemantic(sc);
 2285 
 2286             auto ae = new DeclarationExp(loc, gate);
 2287             eprefix = ae.expressionSemantic(sc);
 2288         }
 2289 
 2290         for (ptrdiff_t i = start; i != end; i += step)
 2291         {
 2292             Expression arg = (*arguments)[i];
 2293 
 2294             Parameter parameter = (i >= nparams ? null : tf.parameterList[i]);
 2295             const bool isRef = parameter && parameter.isReference();
 2296             const bool isLazy = (parameter && (parameter.storageClass & STC.lazy_));
 2297 
 2298             /* Skip lazy parameters
 2299              */
 2300             if (isLazy)
 2301                 continue;
 2302 
 2303             /* Do we have a gate? Then we have a prefix and we're not yet past the last throwing arg.
 2304              * Declare a temporary variable for this arg and append that declaration to 'eprefix',
 2305              * which will implicitly take care of potential problem 2) for this arg.
 2306              * 'eprefix' will therefore finally contain all args up to and including the last
 2307              * potentially throwing arg, excluding all lazy parameters.
 2308              */
 2309             if (gate)
 2310             {
 2311                 const bool needsDtor = (!isRef && arg.type.needsDestruction() && i != lastthrow);
 2312 
 2313                 /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor)
 2314                  */
 2315                 auto tmp = copyToTemp(0,
 2316                     needsDtor ? "__pfx" : "__pfy",
 2317                     !isRef ? arg : arg.addressOf());
 2318                 tmp.dsymbolSemantic(sc);
 2319 
 2320                 /* Modify the destructor so it only runs if gate==false, i.e.,
 2321                  * only if there was a throw while constructing the args
 2322                  */
 2323                 if (!needsDtor)
 2324                 {
 2325                     if (tmp.edtor)
 2326                     {
 2327                         assert(i == lastthrow);
 2328                         tmp.edtor = null;
 2329                     }
 2330                 }
 2331                 else
 2332                 {
 2333                     // edtor => (__gate || edtor)
 2334                     assert(tmp.edtor);
 2335                     Expression e = tmp.edtor;
 2336                     e = new LogicalExp(e.loc, TOK.orOr, new VarExp(e.loc, gate), e);
 2337                     tmp.edtor = e.expressionSemantic(sc);
 2338                     //printf("edtor: %s\n", tmp.edtor.toChars());
 2339                 }
 2340 
 2341                 // eprefix => (eprefix, auto __pfx/y = arg)
 2342                 auto ae = new DeclarationExp(loc, tmp);
 2343                 eprefix = Expression.combine(eprefix, ae.expressionSemantic(sc));
 2344 
 2345                 // arg => __pfx/y
 2346                 arg = new VarExp(loc, tmp);
 2347                 arg = arg.expressionSemantic(sc);
 2348                 if (isRef)
 2349                 {
 2350                     arg = new PtrExp(loc, arg);
 2351                     arg = arg.expressionSemantic(sc);
 2352                 }
 2353 
 2354                 /* Last throwing arg? Then finalize eprefix => (eprefix, gate = true),
 2355                  * i.e., disable the dtors right after constructing the last throwing arg.
 2356                  * From now on, the callee will take care of destructing the args because
 2357                  * the args are implicitly moved into function parameters.
 2358                  *
 2359                  * Set gate to null to let the next iterations know they don't need to
 2360                  * append to eprefix anymore.
 2361                  */
 2362                 if (i == lastthrow)
 2363                 {
 2364                     auto e = new AssignExp(gate.loc, new VarExp(gate.loc, gate), IntegerExp.createBool(true));
 2365                     eprefix = Expression.combine(eprefix, e.expressionSemantic(sc));
 2366                     gate = null;
 2367                 }
 2368             }
 2369             else
 2370             {
 2371                 /* No gate, no prefix to append to.
 2372                  * Handle problem 2) by calling the copy constructor for value structs
 2373                  * (or static arrays of them) if appropriate.
 2374                  */
 2375                 Type tv = arg.type.baseElemOf();
 2376                 if (!isRef && tv.ty == Tstruct)
 2377                     arg = doCopyOrMove(sc, arg, parameter ? parameter.type : null);
 2378             }
 2379 
 2380             (*arguments)[i] = arg;
 2381         }
 2382     }
 2383     //if (eprefix) printf("eprefix: %s\n", eprefix.toChars());
 2384 
 2385     /* Test compliance with DIP1021
 2386      */
 2387     if (global.params.useDIP1021 &&
 2388         tf.trust != TRUST.system && tf.trust != TRUST.trusted)
 2389         err |= checkMutableArguments(sc, fd, tf, ethis, arguments, false);
 2390 
 2391     // If D linkage and variadic, add _arguments[] as first argument
 2392     if (tf.isDstyleVariadic())
 2393     {
 2394         assert(arguments.dim >= nparams);
 2395 
 2396         auto args = new Parameters(arguments.dim - nparams);
 2397         for (size_t i = 0; i < arguments.dim - nparams; i++)
 2398         {
 2399             auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
 2400             (*args)[i] = arg;
 2401         }
 2402         auto tup = new TypeTuple(args);
 2403         Expression e = (new TypeidExp(loc, tup)).expressionSemantic(sc);
 2404         arguments.insert(0, e);
 2405     }
 2406 
 2407     /* Determine function return type: tret
 2408      */
 2409     Type tret = tf.next;
 2410     if (isCtorCall)
 2411     {
 2412         //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd.toChars(), fd.type.toChars(),
 2413         //    wildmatch, tf.isWild(), fd.isReturnIsolated());
 2414         if (!tthis)
 2415         {
 2416             assert(sc.intypeof || global.errors);
 2417             tthis = fd.isThis().type.addMod(fd.type.mod);
 2418         }
 2419         if (tf.isWild() && !fd.isReturnIsolated())
 2420         {
 2421             if (wildmatch)
 2422                 tret = tret.substWildTo(wildmatch);
 2423             int offset;
 2424             if (!tret.implicitConvTo(tthis) && !(MODimplicitConv(tret.mod, tthis.mod) && tret.isBaseOf(tthis, &offset) && offset == 0))
 2425             {
 2426                 const(char)* s1 = tret.isNaked() ? " mutable" : tret.modToChars();
 2427                 const(char)* s2 = tthis.isNaked() ? " mutable" : tthis.modToChars();
 2428                 .error(loc, "`inout` constructor `%s` creates%s object, not%s", fd.toPrettyChars(), s1, s2);
 2429                 err = true;
 2430             }
 2431         }
 2432         tret = tthis;
 2433     }
 2434     else if (wildmatch && tret)
 2435     {
 2436         /* Adjust function return type based on wildmatch
 2437          */
 2438         //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret.toChars());
 2439         tret = tret.substWildTo(wildmatch);
 2440     }
 2441 
 2442     *prettype = tret;
 2443     *peprefix = eprefix;
 2444     return (err || olderrors != global.errors);
 2445 }
 2446 
 2447 /**
 2448  * Determines whether a symbol represents a module or package
 2449  * (Used as a helper for is(type == module) and is(type == package))
 2450  *
 2451  * Params:
 2452  *  sym = the symbol to be checked
 2453  *
 2454  * Returns:
 2455  *  the symbol which `sym` represents (or `null` if it doesn't represent a `Package`)
 2456  */
 2457 Package resolveIsPackage(Dsymbol sym)
 2458 {
 2459     Package pkg;
 2460     if (Import imp = sym.isImport())
 2461     {
 2462         if (imp.pkg is null)
 2463         {
 2464             .error(sym.loc, "Internal Compiler Error: unable to process forward-referenced import `%s`",
 2465                     imp.toChars());
 2466             assert(0);
 2467         }
 2468         pkg = imp.pkg;
 2469     }
 2470     else if (auto mod = sym.isModule())
 2471         pkg = mod.isPackageFile ? mod.pkg : sym.isPackage();
 2472     else
 2473         pkg = sym.isPackage();
 2474     if (pkg)
 2475         pkg.resolvePKGunknown();
 2476     return pkg;
 2477 }
 2478 
 2479 private Module loadStdMath()
 2480 {
 2481     __gshared Import impStdMath = null;
 2482     if (!impStdMath)
 2483     {
 2484         auto a = new Identifiers();
 2485         a.push(Id.std);
 2486         auto s = new Import(Loc.initial, a, Id.math, null, false);
 2487         // Module.load will call fatal() if there's no std.math available.
 2488         // Gag the error here, pushing the error handling to the caller.
 2489         uint errors = global.startGagging();
 2490         s.load(null);
 2491         if (s.mod)
 2492         {
 2493             s.mod.importAll(null);
 2494             s.mod.dsymbolSemantic(null);
 2495         }
 2496         global.endGagging(errors);
 2497         impStdMath = s;
 2498     }
 2499     return impStdMath.mod;
 2500 }
 2501 
 2502 private extern (C++) final class ExpressionSemanticVisitor : Visitor
 2503 {
 2504     alias visit = Visitor.visit;
 2505 
 2506     Scope* sc;
 2507     Expression result;
 2508 
 2509     this(Scope* sc)
 2510     {
 2511         this.sc = sc;
 2512     }
 2513 
 2514     private void setError()
 2515     {
 2516         result = ErrorExp.get();
 2517     }
 2518 
 2519     /**************************
 2520      * Semantically analyze Expression.
 2521      * Determine types, fold constants, etc.
 2522      */
 2523     override void visit(Expression e)
 2524     {
 2525         static if (LOGSEMANTIC)
 2526         {
 2527             printf("Expression::semantic() %s\n", e.toChars());
 2528         }
 2529         if (e.type)
 2530             e.type = e.type.typeSemantic(e.loc, sc);
 2531         else
 2532             e.type = Type.tvoid;
 2533         result = e;
 2534     }
 2535 
 2536     override void visit(IntegerExp e)
 2537     {
 2538         assert(e.type);
 2539         if (e.type.ty == Terror)
 2540             return setError();
 2541 
 2542         assert(e.type.deco);
 2543         e.setInteger(e.getInteger());
 2544         result = e;
 2545     }
 2546 
 2547     override void visit(RealExp e)
 2548     {
 2549         if (!e.type)
 2550             e.type = Type.tfloat64;
 2551         else
 2552             e.type = e.type.typeSemantic(e.loc, sc);
 2553         result = e;
 2554     }
 2555 
 2556     override void visit(ComplexExp e)
 2557     {
 2558         if (!e.type)
 2559             e.type = Type.tcomplex80;
 2560         else
 2561             e.type = e.type.typeSemantic(e.loc, sc);
 2562         result = e;
 2563     }
 2564 
 2565     override void visit(IdentifierExp exp)
 2566     {
 2567         static if (LOGSEMANTIC)
 2568         {
 2569             printf("IdentifierExp::semantic('%s')\n", exp.ident.toChars());
 2570         }
 2571         if (exp.type) // This is used as the dummy expression
 2572         {
 2573             result = exp;
 2574             return;
 2575         }
 2576 
 2577         Dsymbol scopesym;
 2578         Dsymbol s = sc.search(exp.loc, exp.ident, &scopesym);
 2579         if (s)
 2580         {
 2581             if (s.errors)
 2582                 return setError();
 2583 
 2584             Expression e;
 2585 
 2586             /* See if the symbol was a member of an enclosing 'with'
 2587              */
 2588             WithScopeSymbol withsym = scopesym.isWithScopeSymbol();
 2589             if (withsym && withsym.withstate.wthis && symbolIsVisible(sc, s))
 2590             {
 2591                 /* Disallow shadowing
 2592                  */
 2593                 // First find the scope of the with
 2594                 Scope* scwith = sc;
 2595                 while (scwith.scopesym != scopesym)
 2596                 {
 2597                     scwith = scwith.enclosing;
 2598                     assert(scwith);
 2599                 }
 2600                 // Look at enclosing scopes for symbols with the same name,
 2601                 // in the same function
 2602                 for (Scope* scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing)
 2603                 {
 2604                     Dsymbol s2;
 2605                     if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s != s2)
 2606                     {
 2607                         exp.error("with symbol `%s` is shadowing local symbol `%s`", s.toPrettyChars(), s2.toPrettyChars());
 2608                         return setError();
 2609                     }
 2610                 }
 2611                 s = s.toAlias();
 2612 
 2613                 // Same as wthis.ident
 2614                 //  TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
 2615                 //  The redudancy should be removed.
 2616                 e = new VarExp(exp.loc, withsym.withstate.wthis);
 2617                 e = new DotIdExp(exp.loc, e, exp.ident);
 2618                 e = e.expressionSemantic(sc);
 2619             }
 2620             else
 2621             {
 2622                 if (withsym)
 2623                 {
 2624                     if (withsym.withstate.exp.type.ty != Tvoid)
 2625                     {
 2626                         // 'with (exp)' is a type expression
 2627                         // or 's' is not visible there (for error message)
 2628                         e = new TypeExp(exp.loc, withsym.withstate.exp.type);
 2629                     }
 2630                     else
 2631                     {
 2632                         // 'with (exp)' is a Package/Module
 2633                         e = withsym.withstate.exp;
 2634                     }
 2635                     e = new DotIdExp(exp.loc, e, exp.ident);
 2636                     result = e.expressionSemantic(sc);
 2637                     return;
 2638                 }
 2639 
 2640                 /* If f is really a function template,
 2641                  * then replace f with the function template declaration.
 2642                  */
 2643                 FuncDeclaration f = s.isFuncDeclaration();
 2644                 if (f)
 2645                 {
 2646                     TemplateDeclaration td = getFuncTemplateDecl(f);
 2647                     if (td)
 2648                     {
 2649                         if (td.overroot) // if not start of overloaded list of TemplateDeclaration's
 2650                             td = td.overroot; // then get the start
 2651                         e = new TemplateExp(exp.loc, td, f);
 2652                         e = e.expressionSemantic(sc);
 2653                         result = e;
 2654                         return;
 2655                     }
 2656                 }
 2657 
 2658                 if (global.params.fixAliasThis)
 2659                 {
 2660                     ExpressionDsymbol expDsym = scopesym.isExpressionDsymbol();
 2661                     if (expDsym)
 2662                     {
 2663                         //printf("expDsym = %s\n", expDsym.exp.toChars());
 2664                         result = expDsym.exp.expressionSemantic(sc);
 2665                         return;
 2666                     }
 2667                 }
 2668                 // Haven't done overload resolution yet, so pass 1
 2669                 e = symbolToExp(s, exp.loc, sc, true);
 2670             }
 2671             result = e;
 2672             return;
 2673         }
 2674 
 2675         if (!global.params.fixAliasThis && hasThis(sc))
 2676         {
 2677             for (AggregateDeclaration ad = sc.getStructClassScope(); ad;)
 2678             {
 2679                 if (ad.aliasthis)
 2680                 {
 2681                     Expression e;
 2682                     e = new ThisExp(exp.loc);
 2683                     e = new DotIdExp(exp.loc, e, ad.aliasthis.ident);
 2684                     e = new DotIdExp(exp.loc, e, exp.ident);
 2685                     e = e.trySemantic(sc);
 2686                     if (e)
 2687                     {
 2688                         result = e;
 2689                         return;
 2690                     }
 2691                 }
 2692 
 2693                 auto cd = ad.isClassDeclaration();
 2694                 if (cd && cd.baseClass && cd.baseClass != ClassDeclaration.object)
 2695                 {
 2696                     ad = cd.baseClass;
 2697                     continue;
 2698                 }
 2699                 break;
 2700             }
 2701         }
 2702 
 2703         if (exp.ident == Id.ctfe)
 2704         {
 2705             if (sc.flags & SCOPE.ctfe)
 2706             {
 2707                 exp.error("variable `__ctfe` cannot be read at compile time");
 2708                 return setError();
 2709             }
 2710 
 2711             // Create the magic __ctfe bool variable
 2712             auto vd = new VarDeclaration(exp.loc, Type.tbool, Id.ctfe, null);
 2713             vd.storage_class |= STC.temp;
 2714             vd.semanticRun = PASS.semanticdone;
 2715             Expression e = new VarExp(exp.loc, vd);
 2716             e = e.expressionSemantic(sc);
 2717             result = e;
 2718             return;
 2719         }
 2720 
 2721         // If we've reached this point and are inside a with() scope then we may
 2722         // try one last attempt by checking whether the 'wthis' object supports
 2723         // dynamic dispatching via opDispatch.
 2724         // This is done by rewriting this expression as wthis.ident.
 2725         // The innermost with() scope of the hierarchy to satisfy the condition
 2726         // above wins.
 2727         // https://issues.dlang.org/show_bug.cgi?id=6400
 2728         for (Scope* sc2 = sc; sc2; sc2 = sc2.enclosing)
 2729         {
 2730             if (!sc2.scopesym)
 2731                 continue;
 2732 
 2733             if (auto ss = sc2.scopesym.isWithScopeSymbol())
 2734             {
 2735                 if (ss.withstate.wthis)
 2736                 {
 2737                     Expression e;
 2738                     e = new VarExp(exp.loc, ss.withstate.wthis);
 2739                     e = new DotIdExp(exp.loc, e, exp.ident);
 2740                     e = e.trySemantic(sc);
 2741                     if (e)
 2742                     {
 2743                         result = e;
 2744                         return;
 2745                     }
 2746                 }
 2747                 // Try Type.opDispatch (so the static version)
 2748                 else if (ss.withstate.exp && ss.withstate.exp.op == TOK.type)
 2749                 {
 2750                     if (Type t = ss.withstate.exp.isTypeExp().type)
 2751                     {
 2752                         Expression e;
 2753                         e = new TypeExp(exp.loc, t);
 2754                         e = new DotIdExp(exp.loc, e, exp.ident);
 2755                         e = e.trySemantic(sc);
 2756                         if (e)
 2757                         {
 2758                             result = e;
 2759                             return;
 2760                         }
 2761                     }
 2762                 }
 2763             }
 2764         }
 2765 
 2766         /* Look for what user might have meant
 2767          */
 2768         if (const n = importHint(exp.ident.toString()))
 2769             exp.error("`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
 2770         else if (auto s2 = sc.search_correct(exp.ident))
 2771             exp.error("undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
 2772         else if (const p = Scope.search_correct_C(exp.ident))
 2773             exp.error("undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
 2774         else
 2775             exp.error("undefined identifier `%s`", exp.ident.toChars());
 2776 
 2777         result = ErrorExp.get();
 2778     }
 2779 
 2780     override void visit(DsymbolExp e)
 2781     {
 2782         result = symbolToExp(e.s, e.loc, sc, e.hasOverloads);
 2783     }
 2784 
 2785     override void visit(ThisExp e)
 2786     {
 2787         static if (LOGSEMANTIC)
 2788         {
 2789             printf("ThisExp::semantic()\n");
 2790         }
 2791         if (e.type)
 2792         {
 2793             result = e;
 2794             return;
 2795         }
 2796 
 2797         FuncDeclaration fd = hasThis(sc); // fd is the uplevel function with the 'this' variable
 2798         AggregateDeclaration ad;
 2799 
 2800         /* Special case for typeof(this) and typeof(super) since both
 2801          * should work even if they are not inside a non-static member function
 2802          */
 2803         if (!fd && sc.intypeof == 1)
 2804         {
 2805             // Find enclosing struct or class
 2806             for (Dsymbol s = sc.getStructClassScope(); 1; s = s.parent)
 2807             {
 2808                 if (!s)
 2809                 {
 2810                     e.error("`%s` is not in a class or struct scope", e.toChars());
 2811                     goto Lerr;
 2812                 }
 2813                 ClassDeclaration cd = s.isClassDeclaration();
 2814                 if (cd)
 2815                 {
 2816                     e.type = cd.type;
 2817                     result = e;
 2818                     return;
 2819                 }
 2820                 StructDeclaration sd = s.isStructDeclaration();
 2821                 if (sd)
 2822                 {
 2823                     e.type = sd.type;
 2824                     result = e;
 2825                     return;
 2826                 }
 2827             }
 2828         }
 2829         if (!fd)
 2830             goto Lerr;
 2831 
 2832         assert(fd.vthis);
 2833         e.var = fd.vthis;
 2834         assert(e.var.parent);
 2835         ad = fd.isMemberLocal();
 2836         if (!ad)
 2837             ad = fd.isMember2();
 2838         assert(ad);
 2839         e.type = ad.type.addMod(e.var.type.mod);
 2840 
 2841         if (e.var.checkNestedReference(sc, e.loc))
 2842             return setError();
 2843 
 2844         result = e;
 2845         return;
 2846 
 2847     Lerr:
 2848         e.error("`this` is only defined in non-static member functions, not `%s`", sc.parent.toChars());
 2849         result = ErrorExp.get();
 2850     }
 2851 
 2852     override void visit(SuperExp e)
 2853     {
 2854         static if (LOGSEMANTIC)
 2855         {
 2856             printf("SuperExp::semantic('%s')\n", e.toChars());
 2857         }
 2858         if (e.type)
 2859         {
 2860             result = e;
 2861             return;
 2862         }
 2863 
 2864         FuncDeclaration fd = hasThis(sc);
 2865         ClassDeclaration cd;
 2866         Dsymbol s;
 2867 
 2868         /* Special case for typeof(this) and typeof(super) since both
 2869          * should work even if they are not inside a non-static member function
 2870          */
 2871         if (!fd && sc.intypeof == 1)
 2872         {
 2873             // Find enclosing class
 2874             for (s = sc.getStructClassScope(); 1; s = s.parent)
 2875             {
 2876                 if (!s)
 2877                 {
 2878                     e.error("`%s` is not in a class scope", e.toChars());
 2879                     goto Lerr;
 2880                 }
 2881                 cd = s.isClassDeclaration();
 2882                 if (cd)
 2883                 {
 2884                     cd = cd.baseClass;
 2885                     if (!cd)
 2886                     {
 2887                         e.error("class `%s` has no `super`", s.toChars());
 2888                         goto Lerr;
 2889                     }
 2890                     e.type = cd.type;
 2891                     result = e;
 2892                     return;
 2893                 }
 2894             }
 2895         }
 2896         if (!fd)
 2897             goto Lerr;
 2898 
 2899         e.var = fd.vthis;
 2900         assert(e.var && e.var.parent);
 2901 
 2902         s = fd.toParentDecl();
 2903         if (s.isTemplateDeclaration()) // allow inside template constraint
 2904             s = s.toParent();
 2905         assert(s);
 2906         cd = s.isClassDeclaration();
 2907         //printf("parent is %s %s\n", fd.toParent().kind(), fd.toParent().toChars());
 2908         if (!cd)
 2909             goto Lerr;
 2910         if (!cd.baseClass)
 2911         {
 2912             e.error("no base class for `%s`", cd.toChars());
 2913             e.type = cd.type.addMod(e.var.type.mod);
 2914         }
 2915         else
 2916         {
 2917             e.type = cd.baseClass.type;
 2918             e.type = e.type.castMod(e.var.type.mod);
 2919         }
 2920 
 2921         if (e.var.checkNestedReference(sc, e.loc))
 2922             return setError();
 2923 
 2924         result = e;
 2925         return;
 2926 
 2927     Lerr:
 2928         e.error("`super` is only allowed in non-static class member functions");
 2929         result = ErrorExp.get();
 2930     }
 2931 
 2932     override void visit(NullExp e)
 2933     {
 2934         static if (LOGSEMANTIC)
 2935         {
 2936             printf("NullExp::semantic('%s')\n", e.toChars());
 2937         }
 2938         // NULL is the same as (void *)0
 2939         if (e.type)
 2940         {
 2941             result = e;
 2942             return;
 2943         }
 2944         e.type = Type.tnull;
 2945         result = e;
 2946     }
 2947 
 2948     override void visit(StringExp e)
 2949     {
 2950         static if (LOGSEMANTIC)
 2951         {
 2952             printf("StringExp::semantic() %s\n", e.toChars());
 2953         }
 2954         if (e.type)
 2955         {
 2956             result = e;
 2957             return;
 2958         }
 2959 
 2960         OutBuffer buffer;
 2961         size_t newlen = 0;
 2962         size_t u;
 2963         dchar c;
 2964 
 2965         switch (e.postfix)
 2966         {
 2967         case 'd':
 2968             for (u = 0; u < e.len;)
 2969             {
 2970                 if (const p = utf_decodeChar(e.peekString(), u, c))
 2971                 {
 2972                     e.error("%.*s", cast(int)p.length, p.ptr);
 2973                     return setError();
 2974                 }
 2975                 else
 2976                 {
 2977                     buffer.write4(c);
 2978                     newlen++;
 2979                 }
 2980             }
 2981             buffer.write4(0);
 2982             e.setData(buffer.extractData(), newlen, 4);
 2983             e.type = new TypeDArray(Type.tdchar.immutableOf());
 2984             e.committed = 1;
 2985             break;
 2986 
 2987         case 'w':
 2988             for (u = 0; u < e.len;)
 2989             {
 2990                 if (const p = utf_decodeChar(e.peekString(), u, c))
 2991                 {
 2992                     e.error("%.*s", cast(int)p.length, p.ptr);
 2993                     return setError();
 2994                 }
 2995                 else
 2996                 {
 2997                     buffer.writeUTF16(c);
 2998                     newlen++;
 2999                     if (c >= 0x10000)
 3000                         newlen++;
 3001                 }
 3002             }
 3003             buffer.writeUTF16(0);
 3004             e.setData(buffer.extractData(), newlen, 2);
 3005             e.type = new TypeDArray(Type.twchar.immutableOf());
 3006             e.committed = 1;
 3007             break;
 3008 
 3009         case 'c':
 3010             e.committed = 1;
 3011             goto default;
 3012 
 3013         default:
 3014             e.type = new TypeDArray(Type.tchar.immutableOf());
 3015             break;
 3016         }
 3017         e.type = e.type.typeSemantic(e.loc, sc);
 3018         //type = type.immutableOf();
 3019         //printf("type = %s\n", type.toChars());
 3020 
 3021         result = e;
 3022     }
 3023 
 3024     override void visit(TupleExp exp)
 3025     {
 3026         static if (LOGSEMANTIC)
 3027         {
 3028             printf("+TupleExp::semantic(%s)\n", exp.toChars());
 3029         }
 3030         if (exp.type)
 3031         {
 3032             result = exp;
 3033             return;
 3034         }
 3035 
 3036         if (exp.e0)
 3037             exp.e0 = exp.e0.expressionSemantic(sc);
 3038 
 3039         // Run semantic() on each argument
 3040         bool err = false;
 3041         for (size_t i = 0; i < exp.exps.dim; i++)
 3042         {
 3043             Expression e = (*exp.exps)[i];
 3044             e = e.expressionSemantic(sc);
 3045             if (!e.type)
 3046             {
 3047                 exp.error("`%s` has no value", e.toChars());
 3048                 err = true;
 3049             }
 3050             else if (e.op == TOK.error)
 3051                 err = true;
 3052             else
 3053                 (*exp.exps)[i] = e;
 3054         }
 3055         if (err)
 3056             return setError();
 3057 
 3058         expandTuples(exp.exps);
 3059 
 3060         exp.type = new TypeTuple(exp.exps);
 3061         exp.type = exp.type.typeSemantic(exp.loc, sc);
 3062         //printf("-TupleExp::semantic(%s)\n", toChars());
 3063         result = exp;
 3064     }
 3065 
 3066     override void visit(ArrayLiteralExp e)
 3067     {
 3068         static if (LOGSEMANTIC)
 3069         {
 3070             printf("ArrayLiteralExp::semantic('%s')\n", e.toChars());
 3071         }
 3072         if (e.type)
 3073         {
 3074             result = e;
 3075             return;
 3076         }
 3077 
 3078         /* Perhaps an empty array literal [ ] should be rewritten as null?
 3079          */
 3080 
 3081         if (e.basis)
 3082             e.basis = e.basis.expressionSemantic(sc);
 3083         if (arrayExpressionSemantic(e.elements, sc) || (e.basis && e.basis.op == TOK.error))
 3084             return setError();
 3085 
 3086         expandTuples(e.elements);
 3087 
 3088         Type t0;
 3089         if (e.basis)
 3090             e.elements.push(e.basis);
 3091         bool err = arrayExpressionToCommonType(sc, e.elements, &t0);
 3092         if (e.basis)
 3093             e.basis = e.elements.pop();
 3094         if (err)
 3095             return setError();
 3096 
 3097         e.type = t0.arrayOf();
 3098         e.type = e.type.typeSemantic(e.loc, sc);
 3099 
 3100         /* Disallow array literals of type void being used.
 3101          */
 3102         if (e.elements.dim > 0 && t0.ty == Tvoid)
 3103         {
 3104             e.error("`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
 3105             return setError();
 3106         }
 3107 
 3108         if (global.params.useTypeInfo && Type.dtypeinfo)
 3109             semanticTypeInfo(sc, e.type);
 3110 
 3111         result = e;
 3112     }
 3113 
 3114     override void visit(AssocArrayLiteralExp e)
 3115     {
 3116         static if (LOGSEMANTIC)
 3117         {
 3118             printf("AssocArrayLiteralExp::semantic('%s')\n", e.toChars());
 3119         }
 3120         if (e.type)
 3121         {
 3122             result = e;
 3123             return;
 3124         }
 3125 
 3126         // Run semantic() on each element
 3127         bool err_keys = arrayExpressionSemantic(e.keys, sc);
 3128         bool err_vals = arrayExpressionSemantic(e.values, sc);
 3129         if (err_keys || err_vals)
 3130             return setError();
 3131 
 3132         expandTuples(e.keys);
 3133         expandTuples(e.values);
 3134         if (e.keys.dim != e.values.dim)
 3135         {
 3136             e.error("number of keys is %llu, must match number of values %llu",
 3137                         cast(ulong) e.keys.dim, cast(ulong) e.values.dim);
 3138             return setError();
 3139         }
 3140 
 3141         Type tkey = null;
 3142         Type tvalue = null;
 3143         err_keys = arrayExpressionToCommonType(sc, e.keys, &tkey);
 3144         err_vals = arrayExpressionToCommonType(sc, e.values, &tvalue);
 3145         if (err_keys || err_vals)
 3146             return setError();
 3147 
 3148         if (tkey == Type.terror || tvalue == Type.terror)
 3149             return setError();
 3150 
 3151         e.type = new TypeAArray(tvalue, tkey);
 3152         e.type = e.type.typeSemantic(e.loc, sc);
 3153 
 3154         semanticTypeInfo(sc, e.type);
 3155 
 3156         if (global.params.vsafe)
 3157         {
 3158             if (checkAssocArrayLiteralEscape(sc, e, false))
 3159                 return setError();
 3160         }
 3161 
 3162         result = e;
 3163     }
 3164 
 3165     override void visit(StructLiteralExp e)
 3166     {
 3167         static if (LOGSEMANTIC)
 3168         {
 3169             printf("StructLiteralExp::semantic('%s')\n", e.toChars());
 3170         }
 3171         if (e.type)
 3172         {
 3173             result = e;
 3174             return;
 3175         }
 3176 
 3177         e.sd.size(e.loc);
 3178         if (e.sd.sizeok != Sizeok.done)
 3179             return setError();
 3180 
 3181         // run semantic() on each element
 3182         if (arrayExpressionSemantic(e.elements, sc))
 3183             return setError();
 3184 
 3185         expandTuples(e.elements);
 3186 
 3187         /* Fit elements[] to the corresponding type of field[].
 3188          */
 3189         if (!e.sd.fit(e.loc, sc, e.elements, e.stype))
 3190             return setError();
 3191 
 3192         /* Fill out remainder of elements[] with default initializers for fields[]
 3193          */
 3194         if (!e.sd.fill(e.loc, e.elements, false))
 3195         {
 3196             /* An error in the initializer needs to be recorded as an error
 3197              * in the enclosing function or template, since the initializer
 3198              * will be part of the stuct declaration.
 3199              */
 3200             global.increaseErrorCount();
 3201             return setError();
 3202         }
 3203 
 3204         if (checkFrameAccess(e.loc, sc, e.sd, e.elements.dim))
 3205             return setError();
 3206 
 3207         e.type = e.stype ? e.stype : e.sd.type;
 3208         result = e;
 3209     }
 3210 
 3211     override void visit(TypeExp exp)
 3212     {
 3213         if (exp.type.ty == Terror)
 3214             return setError();
 3215 
 3216         //printf("TypeExp::semantic(%s)\n", exp.type.toChars());
 3217         Expression e;
 3218         Type t;
 3219         Dsymbol s;
 3220 
 3221         dmd.typesem.resolve(exp.type, exp.loc, sc, &e, &t, &s, true);
 3222         if (e)
 3223         {
 3224             // `(Type)` is actually `(var)` so if `(var)` is a member requiring `this`
 3225             // then rewrite as `(this.var)` in case it would be followed by a DotVar
 3226             // to fix https://issues.dlang.org/show_bug.cgi?id=9490
 3227             VarExp ve = e.isVarExp();
 3228             if (ve && ve.var && exp.parens && !ve.var.isStatic() && !(sc.stc & STC.static_) &&
 3229                 sc.func && sc.func.needThis && ve.var.toParent2().isAggregateDeclaration())
 3230             {
 3231                 // printf("apply fix for issue 9490: add `this.` to `%s`...\n", e.toChars());
 3232                 e = new DotVarExp(exp.loc, new ThisExp(exp.loc), ve.var, false);
 3233             }
 3234             //printf("e = %s %s\n", Token::toChars(e.op), e.toChars());
 3235             e = e.expressionSemantic(sc);
 3236         }
 3237         else if (t)
 3238         {
 3239             //printf("t = %d %s\n", t.ty, t.toChars());
 3240             exp.type = t.typeSemantic(exp.loc, sc);
 3241             e = exp;
 3242         }
 3243         else if (s)
 3244         {
 3245             //printf("s = %s %s\n", s.kind(), s.toChars());
 3246             e = symbolToExp(s, exp.loc, sc, true);
 3247         }
 3248         else
 3249             assert(0);
 3250 
 3251         if (global.params.vcomplex)
 3252             exp.type.checkComplexTransition(exp.loc, sc);
 3253 
 3254         result = e;
 3255     }
 3256 
 3257     override void visit(ScopeExp exp)
 3258     {
 3259         static if (LOGSEMANTIC)
 3260         {
 3261             printf("+ScopeExp::semantic(%p '%s')\n", exp, exp.toChars());
 3262         }
 3263         if (exp.type)
 3264         {
 3265             result = exp;
 3266             return;
 3267         }
 3268 
 3269         ScopeDsymbol sds2 = exp.sds;
 3270         TemplateInstance ti = sds2.isTemplateInstance();
 3271         while (ti)
 3272         {
 3273             WithScopeSymbol withsym;
 3274             if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))
 3275                 return setError();
 3276             if (withsym && withsym.withstate.wthis)
 3277             {
 3278                 Expression e = new VarExp(exp.loc, withsym.withstate.wthis);
 3279                 e = new DotTemplateInstanceExp(exp.loc, e, ti);
 3280                 result = e.expressionSemantic(sc);
 3281                 return;
 3282             }
 3283             if (ti.needsTypeInference(sc))
 3284             {
 3285                 if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
 3286                 {
 3287                     Dsymbol p = td.toParentLocal();
 3288                     FuncDeclaration fdthis = hasThis(sc);
 3289                     AggregateDeclaration ad = p ? p.isAggregateDeclaration() : null;
 3290                     if (fdthis && ad && fdthis.isMemberLocal() == ad && (td._scope.stc & STC.static_) == 0)
 3291                     {
 3292                         Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti);
 3293                         result = e.expressionSemantic(sc);
 3294                         return;
 3295                     }
 3296                 }
 3297                 else if (OverloadSet os = ti.tempdecl.isOverloadSet())
 3298                 {
 3299                     FuncDeclaration fdthis = hasThis(sc);
 3300                     AggregateDeclaration ad = os.parent.isAggregateDeclaration();
 3301                     if (fdthis && ad && fdthis.isMemberLocal() == ad)
 3302                     {
 3303                         Expression e = new DotTemplateInstanceExp(exp.loc, new ThisExp(exp.loc), ti);
 3304                         result = e.expressionSemantic(sc);
 3305                         return;
 3306                     }
 3307                 }
 3308                 // ti is an instance which requires IFTI.
 3309                 exp.sds = ti;
 3310                 exp.type = Type.tvoid;
 3311                 result = exp;
 3312                 return;
 3313             }
 3314             ti.dsymbolSemantic(sc);
 3315             if (!ti.inst || ti.errors)
 3316                 return setError();
 3317 
 3318             Dsymbol s = ti.toAlias();
 3319             if (s == ti)
 3320             {
 3321                 exp.sds = ti;
 3322                 exp.type = Type.tvoid;
 3323                 result = exp;
 3324                 return;
 3325             }
 3326             sds2 = s.isScopeDsymbol();
 3327             if (sds2)
 3328             {
 3329                 ti = sds2.isTemplateInstance();
 3330                 //printf("+ sds2 = %s, '%s'\n", sds2.kind(), sds2.toChars());
 3331                 continue;
 3332             }
 3333 
 3334             if (auto v = s.isVarDeclaration())
 3335             {
 3336                 if (!v.type)
 3337                 {
 3338                     exp.error("forward reference of %s `%s`", v.kind(), v.toChars());
 3339                     return setError();
 3340                 }
 3341                 if ((v.storage_class & STC.manifest) && v._init)
 3342                 {
 3343                     /* When an instance that will be converted to a constant exists,
 3344                      * the instance representation "foo!tiargs" is treated like a
 3345                      * variable name, and its recursive appearance check (note that
 3346                      * it's equivalent with a recursive instantiation of foo) is done
 3347                      * separately from the circular initialization check for the
 3348                      * eponymous enum variable declaration.
 3349                      *
 3350                      *  template foo(T) {
 3351                      *    enum bool foo = foo;    // recursive definition check (v.inuse)
 3352                      *  }
 3353                      *  template bar(T) {
 3354                      *    enum bool bar = bar!T;  // recursive instantiation check (ti.inuse)
 3355                      *  }
 3356                      */
 3357                     if (ti.inuse)
 3358                     {
 3359                         exp.error("recursive expansion of %s `%s`", ti.kind(), ti.toPrettyChars());
 3360                         return setError();
 3361                     }
 3362                     v.checkDeprecated(exp.loc, sc);
 3363                     auto e = v.expandInitializer(exp.loc);
 3364                     ti.inuse++;
 3365                     e = e.expressionSemantic(sc);
 3366                     ti.inuse--;
 3367                     result = e;
 3368                     return;
 3369                 }
 3370             }
 3371 
 3372             //printf("s = %s, '%s'\n", s.kind(), s.toChars());
 3373             auto e = symbolToExp(s, exp.loc, sc, true);
 3374             //printf("-1ScopeExp::semantic()\n");
 3375             result = e;
 3376             return;
 3377         }
 3378 
 3379         //printf("sds2 = %s, '%s'\n", sds2.kind(), sds2.toChars());
 3380         //printf("\tparent = '%s'\n", sds2.parent.toChars());
 3381         sds2.dsymbolSemantic(sc);
 3382 
 3383         // (Aggregate|Enum)Declaration
 3384         if (auto t = sds2.getType())
 3385         {
 3386             result = (new TypeExp(exp.loc, t)).expressionSemantic(sc);
 3387             return;
 3388         }
 3389 
 3390         if (auto td = sds2.isTemplateDeclaration())
 3391         {
 3392             result = (new TemplateExp(exp.loc, td)).expressionSemantic(sc);
 3393             return;
 3394         }
 3395 
 3396         exp.sds = sds2;
 3397         exp.type = Type.tvoid;
 3398         //printf("-2ScopeExp::semantic() %s\n", toChars());
 3399         result = exp;
 3400     }
 3401 
 3402     override void visit(NewExp exp)
 3403     {
 3404         static if (LOGSEMANTIC)
 3405         {
 3406             printf("NewExp::semantic() %s\n", exp.toChars());
 3407             if (exp.thisexp)
 3408                 printf("\tthisexp = %s\n", exp.thisexp.toChars());
 3409             printf("\tnewtype: %s\n", exp.newtype.toChars());
 3410         }
 3411         if (exp.type) // if semantic() already run
 3412         {
 3413             result = exp;
 3414             return;
 3415         }
 3416 
 3417         //for error messages if the argument in [] is not convertible to size_t
 3418         const originalNewtype = exp.newtype;
 3419 
 3420         // https://issues.dlang.org/show_bug.cgi?id=11581
 3421         // With the syntax `new T[edim]` or `thisexp.new T[edim]`,
 3422         // T should be analyzed first and edim should go into arguments iff it's
 3423         // not a tuple.
 3424         Expression edim = null;
 3425         if (!exp.arguments && exp.newtype.ty == Tsarray)
 3426         {
 3427             edim = (cast(TypeSArray)exp.newtype).dim;
 3428             exp.newtype = (cast(TypeNext)exp.newtype).next;
 3429         }
 3430 
 3431         ClassDeclaration cdthis = null;
 3432         if (exp.thisexp)
 3433         {
 3434             exp.thisexp = exp.thisexp.expressionSemantic(sc);
 3435             if (exp.thisexp.op == TOK.error)
 3436                 return setError();
 3437 
 3438             cdthis = exp.thisexp.type.isClassHandle();
 3439             if (!cdthis)
 3440             {
 3441                 exp.error("`this` for nested class must be a class type, not `%s`", exp.thisexp.type.toChars());
 3442                 return setError();
 3443             }
 3444 
 3445             sc = sc.push(cdthis);
 3446             exp.type = exp.newtype.typeSemantic(exp.loc, sc);
 3447             sc = sc.pop();
 3448         }
 3449         else
 3450         {
 3451             exp.type = exp.newtype.typeSemantic(exp.loc, sc);
 3452         }
 3453         if (exp.type.ty == Terror)
 3454             return setError();
 3455 
 3456         if (edim)
 3457         {
 3458             if (exp.type.toBasetype().ty == Ttuple)
 3459             {
 3460                 // --> new T[edim]
 3461                 exp.type = new TypeSArray(exp.type, edim);
 3462                 exp.type = exp.type.typeSemantic(exp.loc, sc);
 3463                 if (exp.type.ty == Terror)
 3464                     return setError();
 3465             }
 3466             else
 3467             {
 3468                 // --> new T[](edim)
 3469                 exp.arguments = new Expressions();
 3470                 exp.arguments.push(edim);
 3471                 exp.type = exp.type.arrayOf();
 3472             }
 3473         }
 3474 
 3475         exp.newtype = exp.type; // in case type gets cast to something else
 3476         Type tb = exp.type.toBasetype();
 3477         //printf("tb: %s, deco = %s\n", tb.toChars(), tb.deco);
 3478         if (arrayExpressionSemantic(exp.newargs, sc) ||
 3479             preFunctionParameters(sc, exp.newargs))
 3480         {
 3481             return setError();
 3482         }
 3483         if (arrayExpressionSemantic(exp.arguments, sc))
 3484         {
 3485             return setError();
 3486         }
 3487         //https://issues.dlang.org/show_bug.cgi?id=20547
 3488         //exp.arguments are the "parameters" to [], not to a real function
 3489         //so the errors that come from preFunctionParameters are misleading
 3490         if (originalNewtype.ty == Tsarray)
 3491         {
 3492             if (preFunctionParameters(sc, exp.arguments, false))
 3493             {
 3494                 exp.error("cannot create a `%s` with `new`", originalNewtype.toChars());
 3495                 return setError();
 3496             }
 3497         }
 3498         else if (preFunctionParameters(sc, exp.arguments))
 3499         {
 3500             return setError();
 3501         }
 3502 
 3503         if (exp.thisexp && tb.ty != Tclass)
 3504         {
 3505             exp.error("`.new` is only for allocating nested classes, not `%s`", tb.toChars());
 3506             return setError();
 3507         }
 3508 
 3509         const size_t nargs = exp.arguments ? exp.arguments.dim : 0;
 3510         Expression newprefix = null;
 3511 
 3512         if (tb.ty == Tclass)
 3513         {
 3514             auto cd = (cast(TypeClass)tb).sym;
 3515             cd.size(exp.loc);
 3516             if (cd.sizeok != Sizeok.done)
 3517                 return setError();
 3518             if (!cd.ctor)
 3519                 cd.ctor = cd.searchCtor();
 3520             if (cd.noDefaultCtor && !nargs && !cd.defaultCtor)
 3521             {
 3522                 exp.error("default construction is disabled for type `%s`", cd.type.toChars());
 3523                 return setError();
 3524             }
 3525 
 3526             if (cd.isInterfaceDeclaration())
 3527             {
 3528                 exp.error("cannot create instance of interface `%s`", cd.toChars());
 3529                 return setError();
 3530             }
 3531 
 3532             if (cd.isAbstract())
 3533             {
 3534                 exp.error("cannot create instance of abstract class `%s`", cd.toChars());
 3535                 for (size_t i = 0; i < cd.vtbl.dim; i++)
 3536                 {
 3537                     FuncDeclaration fd = cd.vtbl[i].isFuncDeclaration();
 3538                     if (fd && fd.isAbstract())
 3539                     {
 3540                         errorSupplemental(exp.loc, "function `%s` is not implemented",
 3541                             fd.toFullSignature());
 3542                     }
 3543                 }
 3544                 return setError();
 3545             }
 3546             // checkDeprecated() is already done in newtype.typeSemantic().
 3547 
 3548             if (cd.isNested())
 3549             {
 3550                 /* We need a 'this' pointer for the nested class.
 3551                  * Ensure we have the right one.
 3552                  */
 3553                 Dsymbol s = cd.toParentLocal();
 3554 
 3555                 //printf("cd isNested, parent = %s '%s'\n", s.kind(), s.toPrettyChars());
 3556                 if (auto cdn = s.isClassDeclaration())
 3557                 {
 3558                     if (!cdthis)
 3559                     {
 3560                         // Supply an implicit 'this' and try again
 3561                         exp.thisexp = new ThisExp(exp.loc);
 3562                         for (Dsymbol sp = sc.parent; 1; sp = sp.toParentLocal())
 3563                         {
 3564                             if (!sp)
 3565                             {
 3566                                 exp.error("outer class `%s` `this` needed to `new` nested class `%s`",
 3567                                     cdn.toChars(), cd.toChars());
 3568                                 return setError();
 3569                             }
 3570                             ClassDeclaration cdp = sp.isClassDeclaration();
 3571                             if (!cdp)
 3572                                 continue;
 3573                             if (cdp == cdn || cdn.isBaseOf(cdp, null))
 3574                                 break;
 3575                             // Add a '.outer' and try again
 3576                             exp.thisexp = new DotIdExp(exp.loc, exp.thisexp, Id.outer);
 3577                         }
 3578 
 3579                         exp.thisexp = exp.thisexp.expressionSemantic(sc);
 3580                         if (exp.thisexp.op == TOK.error)
 3581                             return setError();
 3582                         cdthis = exp.thisexp.type.isClassHandle();
 3583                     }
 3584                     if (cdthis != cdn && !cdn.isBaseOf(cdthis, null))
 3585                     {
 3586                         //printf("cdthis = %s\n", cdthis.toChars());
 3587                         exp.error("`this` for nested class must be of type `%s`, not `%s`",
 3588                             cdn.toChars(), exp.thisexp.type.toChars());
 3589                         return setError();
 3590                     }
 3591                     if (!MODimplicitConv(exp.thisexp.type.mod, exp.newtype.mod))
 3592                     {
 3593                         exp.error("nested type `%s` should have the same or weaker constancy as enclosing type `%s`",
 3594                             exp.newtype.toChars(), exp.thisexp.type.toChars());
 3595                         return setError();
 3596                     }
 3597                 }
 3598                 else if (exp.thisexp)
 3599                 {
 3600                     exp.error("`.new` is only for allocating nested classes");
 3601                     return setError();
 3602                 }
 3603                 else if (auto fdn = s.isFuncDeclaration())
 3604                 {
 3605                     // make sure the parent context fdn of cd is reachable from sc
 3606                     if (!ensureStaticLinkTo(sc.parent, fdn))
 3607                     {
 3608                         exp.error("outer function context of `%s` is needed to `new` nested class `%s`",
 3609                             fdn.toPrettyChars(), cd.toPrettyChars());
 3610                         return setError();
 3611                     }
 3612                 }
 3613                 else
 3614                     assert(0);
 3615             }
 3616             else if (exp.thisexp)
 3617             {
 3618                 exp.error("`.new` is only for allocating nested classes");
 3619                 return setError();
 3620             }
 3621 
 3622             if (cd.vthis2)
 3623             {
 3624                 if (AggregateDeclaration ad2 = cd.isMember2())
 3625                 {
 3626                     Expression te = new ThisExp(exp.loc).expressionSemantic(sc);
 3627                     if (te.op != TOK.error)
 3628                         te = getRightThis(exp.loc, sc, ad2, te, cd);
 3629                     if (te.op == TOK.error)
 3630                     {
 3631                         exp.error("need `this` of type `%s` needed to `new` nested class `%s`", ad2.toChars(), cd.toChars());
 3632                         return setError();
 3633                     }
 3634                 }
 3635             }
 3636 
 3637             if (cd.aggNew)
 3638             {
 3639                 // Prepend the size argument to newargs[]
 3640                 Expression e = new IntegerExp(exp.loc, cd.size(exp.loc), Type.tsize_t);
 3641                 if (!exp.newargs)
 3642                     exp.newargs = new Expressions();
 3643                 exp.newargs.shift(e);
 3644 
 3645                 FuncDeclaration f = resolveFuncCall(exp.loc, sc, cd.aggNew, null, tb, exp.newargs, FuncResolveFlag.standard);
 3646                 if (!f || f.errors)
 3647                     return setError();
 3648 
 3649                 checkFunctionAttributes(exp, sc, f);
 3650                 checkAccess(cd, exp.loc, sc, f);
 3651 
 3652                 TypeFunction tf = cast(TypeFunction)f.type;
 3653                 Type rettype;
 3654                 if (functionParameters(exp.loc, sc, tf, null, null, exp.newargs, f, &rettype, &newprefix))
 3655                     return setError();
 3656 
 3657                 exp.allocator = f.isNewDeclaration();
 3658                 assert(exp.allocator);
 3659             }
 3660             else
 3661             {
 3662                 if (exp.newargs && exp.newargs.dim)
 3663                 {
 3664                     exp.error("no allocator for `%s`", cd.toChars());
 3665                     return setError();
 3666                 }
 3667             }
 3668 
 3669             if (cd.ctor)
 3670             {
 3671                 FuncDeclaration f = resolveFuncCall(exp.loc, sc, cd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard);
 3672                 if (!f || f.errors)
 3673                     return setError();
 3674 
 3675                 checkFunctionAttributes(exp, sc, f);
 3676                 checkAccess(cd, exp.loc, sc, f);
 3677 
 3678                 TypeFunction tf = cast(TypeFunction)f.type;
 3679                 if (!exp.arguments)
 3680                     exp.arguments = new Expressions();
 3681                 if (functionParameters(exp.loc, sc, tf, null, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))
 3682                     return setError();
 3683 
 3684                 exp.member = f.isCtorDeclaration();
 3685                 assert(exp.member);
 3686             }
 3687             else
 3688             {
 3689                 if (nargs)
 3690                 {
 3691                     exp.error("no constructor for `%s`", cd.toChars());
 3692                     return setError();
 3693                 }
 3694 
 3695                 // https://issues.dlang.org/show_bug.cgi?id=19941
 3696                 // Run semantic on all field initializers to resolve any forward
 3697                 // references. This is the same as done for structs in sd.fill().
 3698                 for (ClassDeclaration c = cd; c; c = c.baseClass)
 3699                 {
 3700                     foreach (v; c.fields)
 3701                     {
 3702                         if (v.inuse || v._scope is null || v._init is null ||
 3703                             v._init.isVoidInitializer())
 3704                             continue;
 3705                         v.inuse++;
 3706                         v._init = v._init.initializerSemantic(v._scope, v.type, INITinterpret);
 3707                         v.inuse--;
 3708                     }
 3709                 }
 3710             }
 3711         }
 3712         else if (tb.ty == Tstruct)
 3713         {
 3714             auto sd = (cast(TypeStruct)tb).sym;
 3715             sd.size(exp.loc);
 3716             if (sd.sizeok != Sizeok.done)
 3717                 return setError();
 3718             if (!sd.ctor)
 3719                 sd.ctor = sd.searchCtor();
 3720             if (sd.noDefaultCtor && !nargs)
 3721             {
 3722                 exp.error("default construction is disabled for type `%s`", sd.type.toChars());
 3723                 return setError();
 3724             }
 3725             // checkDeprecated() is already done in newtype.typeSemantic().
 3726 
 3727             if (sd.aggNew)
 3728             {
 3729                 // Prepend the uint size argument to newargs[]
 3730                 Expression e = new IntegerExp(exp.loc, sd.size(exp.loc), Type.tsize_t);
 3731                 if (!exp.newargs)
 3732                     exp.newargs = new Expressions();
 3733                 exp.newargs.shift(e);
 3734 
 3735                 FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.aggNew, null, tb, exp.newargs, FuncResolveFlag.standard);
 3736                 if (!f || f.errors)
 3737                     return setError();
 3738 
 3739                 checkFunctionAttributes(exp, sc, f);
 3740                 checkAccess(sd, exp.loc, sc, f);
 3741 
 3742                 TypeFunction tf = cast(TypeFunction)f.type;
 3743                 Type rettype;
 3744                 if (functionParameters(exp.loc, sc, tf, null, null, exp.newargs, f, &rettype, &newprefix))
 3745                     return setError();
 3746 
 3747                 exp.allocator = f.isNewDeclaration();
 3748                 assert(exp.allocator);
 3749             }
 3750             else
 3751             {
 3752                 if (exp.newargs && exp.newargs.dim)
 3753                 {
 3754                     exp.error("no allocator for `%s`", sd.toChars());
 3755                     return setError();
 3756                 }
 3757             }
 3758 
 3759             if (sd.ctor && nargs)
 3760             {
 3761                 FuncDeclaration f = resolveFuncCall(exp.loc, sc, sd.ctor, null, tb, exp.arguments, FuncResolveFlag.standard);
 3762                 if (!f || f.errors)
 3763                     return setError();
 3764 
 3765                 checkFunctionAttributes(exp, sc, f);
 3766                 checkAccess(sd, exp.loc, sc, f);
 3767 
 3768                 TypeFunction tf = cast(TypeFunction)f.type;
 3769                 if (!exp.arguments)
 3770                     exp.arguments = new Expressions();
 3771                 if (functionParameters(exp.loc, sc, tf, null, exp.type, exp.arguments, f, &exp.type, &exp.argprefix))
 3772                     return setError();
 3773 
 3774                 exp.member = f.isCtorDeclaration();
 3775                 assert(exp.member);
 3776 
 3777                 if (checkFrameAccess(exp.loc, sc, sd, sd.fields.dim))
 3778                     return setError();
 3779             }
 3780             else
 3781             {
 3782                 if (!exp.arguments)
 3783                     exp.arguments = new Expressions();
 3784 
 3785                 if (!sd.fit(exp.loc, sc, exp.arguments, tb))
 3786                     return setError();
 3787 
 3788                 if (!sd.fill(exp.loc, exp.arguments, false))
 3789                     return setError();
 3790 
 3791                 if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))
 3792                     return setError();
 3793 
 3794                 /* Since a `new` allocation may escape, check each of the arguments for escaping
 3795                  */
 3796                 if (global.params.vsafe)
 3797                 {
 3798                     foreach (arg; *exp.arguments)
 3799                     {
 3800                         if (arg && checkNewEscape(sc, arg, false))
 3801                             return setError();
 3802                     }
 3803                 }
 3804             }
 3805 
 3806             exp.type = exp.type.pointerTo();
 3807         }
 3808         else if (tb.ty == Tarray)
 3809         {
 3810             if (!nargs)
 3811             {
 3812                 // https://issues.dlang.org/show_bug.cgi?id=20422
 3813                 // Without this check the compiler would give a misleading error
 3814                 exp.error("missing length argument for array");
 3815                 return setError();
 3816             }
 3817 
 3818             Type tn = tb.nextOf().baseElemOf();
 3819             Dsymbol s = tn.toDsymbol(sc);
 3820             AggregateDeclaration ad = s ? s.isAggregateDeclaration() : null;
 3821             if (ad && ad.noDefaultCtor)
 3822             {
 3823                 exp.error("default construction is disabled for type `%s`", tb.nextOf().toChars());
 3824                 return setError();
 3825             }
 3826             for (size_t i = 0; i < nargs; i++)
 3827             {
 3828                 if (tb.ty != Tarray)
 3829                 {
 3830                     exp.error("too many arguments for array");
 3831                     return setError();
 3832                 }
 3833 
 3834                 Expression arg = (*exp.arguments)[i];
 3835                 arg = resolveProperties(sc, arg);
 3836                 arg = arg.implicitCastTo(sc, Type.tsize_t);
 3837                 if (arg.op == TOK.error)
 3838                     return setError();
 3839                 arg = arg.optimize(WANTvalue);
 3840                 if (arg.op == TOK.int64 && cast(sinteger_t)arg.toInteger() < 0)
 3841                 {
 3842                     exp.error("negative array index `%s`", arg.toChars());
 3843                     return setError();
 3844                 }
 3845                 (*exp.arguments)[i] = arg;
 3846                 tb = (cast(TypeDArray)tb).next.toBasetype();
 3847             }
 3848         }
 3849         else if (tb.isscalar())
 3850         {
 3851             if (!nargs)
 3852             {
 3853             }
 3854             else if (nargs == 1)
 3855             {
 3856                 Expression e = (*exp.arguments)[0];
 3857                 e = e.implicitCastTo(sc, tb);
 3858                 (*exp.arguments)[0] = e;
 3859             }
 3860             else
 3861             {
 3862                 exp.error("more than one argument for construction of `%s`", exp.type.toChars());
 3863                 return setError();
 3864             }
 3865 
 3866             exp.type = exp.type.pointerTo();
 3867         }
 3868         else
 3869         {
 3870             exp.error("cannot create a `%s` with `new`", exp.type.toChars());
 3871             return setError();
 3872         }
 3873 
 3874         //printf("NewExp: '%s'\n", toChars());
 3875         //printf("NewExp:type '%s'\n", type.toChars());
 3876         semanticTypeInfo(sc, exp.type);
 3877 
 3878         if (newprefix)
 3879         {
 3880             result = Expression.combine(newprefix, exp);
 3881             return;
 3882         }
 3883         result = exp;
 3884     }
 3885 
 3886     override void visit(NewAnonClassExp e)
 3887     {
 3888         static if (LOGSEMANTIC)
 3889         {
 3890             printf("NewAnonClassExp::semantic() %s\n", e.toChars());
 3891             //printf("thisexp = %p\n", thisexp);
 3892             //printf("type: %s\n", type.toChars());
 3893         }
 3894 
 3895         Expression d = new DeclarationExp(e.loc, e.cd);
 3896         sc = sc.push(); // just create new scope
 3897         sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE
 3898         d = d.expressionSemantic(sc);
 3899         sc = sc.pop();
 3900 
 3901         if (!e.cd.errors && sc.intypeof && !sc.parent.inNonRoot())
 3902         {
 3903             ScopeDsymbol sds = sc.tinst ? cast(ScopeDsymbol)sc.tinst : sc._module;
 3904             if (!sds.members)
 3905                 sds.members = new Dsymbols();
 3906             sds.members.push(e.cd);
 3907         }
 3908 
 3909         Expression n = new NewExp(e.loc, e.thisexp, e.newargs, e.cd.type, e.arguments);
 3910 
 3911         Expression c = new CommaExp(e.loc, d, n);
 3912         result = c.expressionSemantic(sc);
 3913     }
 3914 
 3915     override void visit(SymOffExp e)
 3916     {
 3917         static if (LOGSEMANTIC)
 3918         {
 3919             printf("SymOffExp::semantic('%s')\n", e.toChars());
 3920         }
 3921         //var.dsymbolSemantic(sc);
 3922         if (!e.type)
 3923             e.type = e.var.type.pointerTo();
 3924 
 3925         if (auto v = e.var.isVarDeclaration())
 3926         {
 3927             if (v.checkNestedReference(sc, e.loc))
 3928                 return setError();
 3929         }
 3930         else if (auto f = e.var.isFuncDeclaration())
 3931         {
 3932             if (f.checkNestedReference(sc, e.loc))
 3933                 return setError();
 3934         }
 3935 
 3936         result = e;
 3937     }
 3938 
 3939     override void visit(VarExp e)
 3940     {
 3941         static if (LOGSEMANTIC)
 3942         {
 3943             printf("VarExp::semantic(%s)\n", e.toChars());
 3944         }
 3945 
 3946         auto vd = e.var.isVarDeclaration();
 3947         auto fd = e.var.isFuncDeclaration();
 3948 
 3949         if (fd)
 3950         {
 3951             //printf("L%d fd = %s\n", __LINE__, f.toChars());
 3952             if (!fd.functionSemantic())
 3953                 return setError();
 3954         }
 3955 
 3956         if (!e.type)
 3957             e.type = e.var.type;
 3958         if (e.type && !e.type.deco)
 3959         {
 3960             auto decl = e.var.isDeclaration();
 3961             if (decl)
 3962                 decl.inuse++;
 3963             e.type = e.type.typeSemantic(e.loc, sc);
 3964             if (decl)
 3965                 decl.inuse--;
 3966         }
 3967 
 3968         /* Fix for 1161 doesn't work because it causes protection
 3969          * problems when instantiating imported templates passing private
 3970          * variables as alias template parameters.
 3971          */
 3972         //checkAccess(loc, sc, NULL, var);
 3973 
 3974         if (vd)
 3975         {
 3976             if (vd.checkNestedReference(sc, e.loc))
 3977                 return setError();
 3978 
 3979             // https://issues.dlang.org/show_bug.cgi?id=12025
 3980             // If the variable is not actually used in runtime code,
 3981             // the purity violation error is redundant.
 3982             //checkPurity(sc, vd);
 3983         }
 3984         else if (fd)
 3985         {
 3986             // TODO: If fd isn't yet resolved its overload, the checkNestedReference
 3987             // call would cause incorrect validation.
 3988             // Maybe here should be moved in CallExp, or AddrExp for functions.
 3989             if (fd.checkNestedReference(sc, e.loc))
 3990                 return setError();
 3991         }
 3992         else if (auto od = e.var.isOverDeclaration())
 3993         {
 3994             e.type = Type.tvoid; // ambiguous type?
 3995         }
 3996 
 3997         result = e;
 3998     }
 3999 
 4000     override void visit(FuncExp exp)
 4001     {
 4002         static if (LOGSEMANTIC)
 4003         {
 4004             printf("FuncExp::semantic(%s)\n", exp.toChars());
 4005             if (exp.fd.treq)
 4006                 printf("  treq = %s\n", exp.fd.treq.toChars());
 4007         }
 4008 
 4009         if (exp.type)
 4010         {
 4011             result = exp;
 4012             return;
 4013         }
 4014 
 4015         Expression e = exp;
 4016         uint olderrors;
 4017 
 4018         sc = sc.push(); // just create new scope
 4019         sc.flags &= ~SCOPE.ctfe; // temporary stop CTFE
 4020         sc.protection = Prot(Prot.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=12506
 4021 
 4022         /* fd.treq might be incomplete type,
 4023             * so should not semantic it.
 4024             * void foo(T)(T delegate(int) dg){}
 4025             * foo(a=>a); // in IFTI, treq == T delegate(int)
 4026             */
 4027         //if (fd.treq)
 4028         //    fd.treq = fd.treq.dsymbolSemantic(loc, sc);
 4029 
 4030         exp.genIdent(sc);
 4031 
 4032         // Set target of return type inference
 4033         if (exp.fd.treq && !exp.fd.type.nextOf())
 4034         {
 4035             TypeFunction tfv = null;
 4036             if (exp.fd.treq.ty == Tdelegate || (exp.fd.treq.ty == Tpointer && exp.fd.treq.nextOf().ty == Tfunction))
 4037                 tfv = cast(TypeFunction)exp.fd.treq.nextOf();
 4038             if (tfv)
 4039             {
 4040                 TypeFunction tfl = cast(TypeFunction)exp.fd.type;
 4041                 tfl.next = tfv.nextOf();
 4042             }
 4043         }
 4044 
 4045         //printf("td = %p, treq = %p\n", td, fd.treq);
 4046         if (exp.td)
 4047         {
 4048             assert(exp.td.parameters && exp.td.parameters.dim);
 4049             exp.td.dsymbolSemantic(sc);
 4050             exp.type = Type.tvoid; // temporary type
 4051 
 4052             if (exp.fd.treq) // defer type determination
 4053             {
 4054                 FuncExp fe;
 4055                 if (exp.matchType(exp.fd.treq, sc, &fe) > MATCH.nomatch)
 4056                     e = fe;
 4057                 else
 4058                     e = ErrorExp.get();
 4059             }
 4060             goto Ldone;
 4061         }
 4062 
 4063         olderrors = global.errors;
 4064         exp.fd.dsymbolSemantic(sc);
 4065         if (olderrors == global.errors)
 4066         {
 4067             exp.fd.semantic2(sc);
 4068             if (olderrors == global.errors)
 4069                 exp.fd.semantic3(sc);
 4070         }
 4071         if (olderrors != global.errors)
 4072         {
 4073             if (exp.fd.type && exp.fd.type.ty == Tfunction && !exp.fd.type.nextOf())
 4074                 (cast(TypeFunction)exp.fd.type).next = Type.terror;
 4075             e = ErrorExp.get();
 4076             goto Ldone;
 4077         }
 4078 
 4079         // Type is a "delegate to" or "pointer to" the function literal
 4080         if ((exp.fd.isNested() && exp.fd.tok == TOK.delegate_) || (exp.tok == TOK.reserved && exp.fd.treq && exp.fd.treq.ty == Tdelegate))
 4081         {
 4082             exp.type = new TypeDelegate(exp.fd.type);
 4083             exp.type = exp.type.typeSemantic(exp.loc, sc);
 4084 
 4085             exp.fd.tok = TOK.delegate_;
 4086         }
 4087         else
 4088         {
 4089             exp.type = new TypePointer(exp.fd.type);
 4090             exp.type = exp.type.typeSemantic(exp.loc, sc);
 4091             //type = fd.type.pointerTo();
 4092 
 4093             /* A lambda expression deduced to function pointer might become
 4094                 * to a delegate literal implicitly.
 4095                 *
 4096                 *   auto foo(void function() fp) { return 1; }
 4097                 *   assert(foo({}) == 1);
 4098                 *
 4099                 * So, should keep fd.tok == TOKreserve if fd.treq == NULL.
 4100                 */
 4101             if (exp.fd.treq && exp.fd.treq.ty == Tpointer)
 4102             {
 4103                 // change to non-nested
 4104                 exp.fd.tok = TOK.function_;
 4105                 exp.fd.vthis = null;
 4106             }
 4107         }
 4108         exp.fd.tookAddressOf++;
 4109 
 4110     Ldone:
 4111         sc = sc.pop();
 4112         result = e;
 4113     }
 4114 
 4115     /**
 4116      * Perform semantic analysis on function literals
 4117      *
 4118      * Test the following construct:
 4119      * ---
 4120      * (x, y, z) { return x + y + z; }(42, 84, 1992);
 4121      * ---
 4122      */
 4123     Expression callExpSemantic(FuncExp exp, Scope* sc, Expressions* arguments)
 4124     {
 4125         if ((!exp.type || exp.type == Type.tvoid) && exp.td && arguments && arguments.dim)
 4126         {
 4127             for (size_t k = 0; k < arguments.dim; k++)
 4128             {
 4129                 Expression checkarg = (*arguments)[k];
 4130                 if (checkarg.op == TOK.error)
 4131                     return checkarg;
 4132             }
 4133 
 4134             exp.genIdent(sc);
 4135 
 4136             assert(exp.td.parameters && exp.td.parameters.dim);
 4137             exp.td.dsymbolSemantic(sc);
 4138 
 4139             TypeFunction tfl = cast(TypeFunction)exp.fd.type;
 4140             size_t dim = tfl.parameterList.length;
 4141             if (arguments.dim < dim)
 4142             {
 4143                 // Default arguments are always typed, so they don't need inference.
 4144                 Parameter p = tfl.parameterList[arguments.dim];
 4145                 if (p.defaultArg)
 4146                     dim = arguments.dim;
 4147             }
 4148 
 4149             if ((tfl.parameterList.varargs == VarArg.none && arguments.dim > dim) ||
 4150                 arguments.dim < dim)
 4151             {
 4152                 OutBuffer buf;
 4153                 foreach (idx, ref arg; *arguments)
 4154                     buf.printf("%s%s", (idx ? ", ".ptr : "".ptr), arg.type.toChars());
 4155                 exp.error("function literal `%s%s` is not callable using argument types `(%s)`",
 4156                           exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
 4157                           buf.peekChars());
 4158                 exp.errorSupplemental("too %s arguments, expected `%d`, got `%d`",
 4159                                       arguments.dim < dim ? "few".ptr : "many".ptr,
 4160                                       cast(int)dim, cast(int)arguments.dim);
 4161                 return ErrorExp.get();
 4162             }
 4163 
 4164             auto tiargs = new Objects();
 4165             tiargs.reserve(exp.td.parameters.dim);
 4166 
 4167             for (size_t i = 0; i < exp.td.parameters.dim; i++)
 4168             {
 4169                 TemplateParameter tp = (*exp.td.parameters)[i];
 4170                 assert(dim <= tfl.parameterList.length);
 4171                 foreach (u, p; tfl.parameterList)
 4172                 {
 4173                     if (u == dim)
 4174                         break;
 4175 
 4176                     if (p.type.ty == Tident && (cast(TypeIdentifier)p.type).ident == tp.ident)
 4177                     {
 4178                         Expression e = (*arguments)[u];
 4179                         tiargs.push(e.type);
 4180                         break;
 4181                     }
 4182                 }
 4183             }
 4184 
 4185             auto ti = new TemplateInstance(exp.loc, exp.td, tiargs);
 4186             return (new ScopeExp(exp.loc, ti)).expressionSemantic(sc);
 4187         }
 4188         return exp.expressionSemantic(sc);
 4189     }
 4190 
 4191     override void visit(CallExp exp)
 4192     {
 4193         static if (LOGSEMANTIC)
 4194         {
 4195             printf("CallExp::semantic() %s\n", exp.toChars());
 4196         }
 4197         if (exp.type)
 4198         {
 4199             result = exp;
 4200             return; // semantic() already run
 4201         }
 4202 
 4203         Objects* tiargs = null; // initial list of template arguments
 4204         Expression ethis = null;
 4205         Type tthis = null;
 4206         Expression e1org = exp.e1;
 4207 
 4208         if (exp.e1.op == TOK.comma)
 4209         {
 4210             /* Rewrite (a,b)(args) as (a,(b(args)))
 4211              */
 4212             auto ce = cast(CommaExp)exp.e1;
 4213             exp.e1 = ce.e2;
 4214             ce.e2 = exp;
 4215             result = ce.expressionSemantic(sc);
 4216             return;
 4217         }
 4218         if (exp.e1.op == TOK.delegate_)
 4219         {
 4220             DelegateExp de = cast(DelegateExp)exp.e1;
 4221             exp.e1 = new DotVarExp(de.loc, de.e1, de.func, de.hasOverloads);
 4222             visit(exp);
 4223             return;
 4224         }
 4225         if (exp.e1.op == TOK.function_)
 4226         {
 4227             if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))
 4228                 return setError();
 4229 
 4230             // Run e1 semantic even if arguments have any errors
 4231             FuncExp fe = cast(FuncExp)exp.e1;
 4232             exp.e1 = callExpSemantic(fe, sc, exp.arguments);
 4233             if (exp.e1.op == TOK.error)
 4234             {
 4235                 result = exp.e1;
 4236                 return;
 4237             }
 4238         }
 4239 
 4240         if (Expression ex = resolveUFCS(sc, exp))
 4241         {
 4242             result = ex;
 4243             return;
 4244         }
 4245 
 4246         /* This recognizes:
 4247          *  foo!(tiargs)(funcargs)
 4248          */
 4249         if (exp.e1.op == TOK.scope_)
 4250         {
 4251             ScopeExp se = cast(ScopeExp)exp.e1;
 4252             TemplateInstance ti = se.sds.isTemplateInstance();
 4253             if (ti)
 4254             {
 4255                 /* Attempt to instantiate ti. If that works, go with it.
 4256                  * If not, go with partial explicit specialization.
 4257                  */
 4258                 WithScopeSymbol withsym;
 4259                 if (!ti.findTempDecl(sc, &withsym) || !ti.semanticTiargs(sc))
 4260                     return setError();
 4261                 if (withsym && withsym.withstate.wthis)
 4262                 {
 4263                     exp.e1 = new VarExp(exp.e1.loc, withsym.withstate.wthis);
 4264                     exp.e1 = new DotTemplateInstanceExp(exp.e1.loc, exp.e1, ti);
 4265                     goto Ldotti;
 4266                 }
 4267                 if (ti.needsTypeInference(sc, 1))
 4268                 {
 4269                     /* Go with partial explicit specialization
 4270                      */
 4271                     tiargs = ti.tiargs;
 4272                     assert(ti.tempdecl);
 4273                     if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
 4274                         exp.e1 = new TemplateExp(exp.loc, td);
 4275                     else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())
 4276                         exp.e1 = new VarExp(exp.loc, od);
 4277                     else
 4278                         exp.e1 = new OverExp(exp.loc, ti.tempdecl.isOverloadSet());
 4279                 }
 4280                 else
 4281                 {
 4282                     Expression e1x = exp.e1.expressionSemantic(sc);
 4283                     if (e1x.op == TOK.error)
 4284                     {
 4285                         result = e1x;
 4286                         return;
 4287                     }
 4288                     exp.e1 = e1x;
 4289                 }
 4290             }
 4291         }
 4292 
 4293         /* This recognizes:
 4294          *  expr.foo!(tiargs)(funcargs)
 4295          */
 4296     Ldotti:
 4297         if (exp.e1.op == TOK.dotTemplateInstance && !exp.e1.type)
 4298         {
 4299             DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)exp.e1;
 4300             TemplateInstance ti = se.ti;
 4301             {
 4302                 /* Attempt to instantiate ti. If that works, go with it.
 4303                  * If not, go with partial explicit specialization.
 4304                  */
 4305                 if (!se.findTempDecl(sc) || !ti.semanticTiargs(sc))
 4306                     return setError();
 4307                 if (ti.needsTypeInference(sc, 1))
 4308                 {
 4309                     /* Go with partial explicit specialization
 4310                      */
 4311                     tiargs = ti.tiargs;
 4312                     assert(ti.tempdecl);
 4313                     if (TemplateDeclaration td = ti.tempdecl.isTemplateDeclaration())
 4314                         exp.e1 = new DotTemplateExp(exp.loc, se.e1, td);
 4315                     else if (OverDeclaration od = ti.tempdecl.isOverDeclaration())
 4316                     {
 4317                         exp.e1 = new DotVarExp(exp.loc, se.e1, od, true);
 4318                     }
 4319                     else
 4320                         exp.e1 = new DotExp(exp.loc, se.e1, new OverExp(exp.loc, ti.tempdecl.isOverloadSet()));
 4321                 }
 4322                 else
 4323                 {
 4324                     Expression e1x = exp.e1.expressionSemantic(sc);
 4325                     if (e1x.op == TOK.error)
 4326                     {
 4327                         result = e1x;
 4328                         return;
 4329                     }
 4330                     exp.e1 = e1x;
 4331                 }
 4332             }
 4333         }
 4334 
 4335     Lagain:
 4336         //printf("Lagain: %s\n", toChars());
 4337         exp.f = null;
 4338         if (exp.e1.op == TOK.this_ || exp.e1.op == TOK.super_)
 4339         {
 4340             // semantic() run later for these
 4341         }
 4342         else
 4343         {
 4344             if (exp.e1.op == TOK.dotIdentifier)
 4345             {
 4346                 DotIdExp die = cast(DotIdExp)exp.e1;
 4347                 exp.e1 = die.expressionSemantic(sc);
 4348                 /* Look for e1 having been rewritten to expr.opDispatch!(string)
 4349                  * We handle such earlier, so go back.
 4350                  * Note that in the rewrite, we carefully did not run semantic() on e1
 4351                  */
 4352                 if (exp.e1.op == TOK.dotTemplateInstance && !exp.e1.type)
 4353                 {
 4354                     goto Ldotti;
 4355                 }
 4356             }
 4357             else
 4358             {
 4359                 __gshared int nest;
 4360                 if (++nest > global.recursionLimit)
 4361                 {
 4362                     exp.error("recursive evaluation of `%s`", exp.toChars());
 4363                     --nest;
 4364                     return setError();
 4365                 }
 4366                 Expression ex = unaSemantic(exp, sc);
 4367                 --nest;
 4368                 if (ex)
 4369                 {
 4370                     result = ex;
 4371                     return;
 4372                 }
 4373             }
 4374 
 4375             /* Look for e1 being a lazy parameter
 4376              */
 4377             if (exp.e1.op == TOK.variable)
 4378             {
 4379                 VarExp ve = cast(VarExp)exp.e1;
 4380                 if (ve.var.storage_class & STC.lazy_)
 4381                 {
 4382                     // lazy parameters can be called without violating purity and safety
 4383                     Type tw = ve.var.type;
 4384                     Type tc = ve.var.type.substWildTo(MODFlags.const_);
 4385                     auto tf = new TypeFunction(ParameterList(), tc, LINK.d, STC.safe | STC.pure_);
 4386                     (tf = cast(TypeFunction)tf.typeSemantic(exp.loc, sc)).next = tw; // hack for bug7757
 4387                     auto t = new TypeDelegate(tf);
 4388                     ve.type = t.typeSemantic(exp.loc, sc);
 4389                 }
 4390                 VarDeclaration v = ve.var.isVarDeclaration();
 4391                 if (v && ve.checkPurity(sc, v))
 4392                     return setError();
 4393             }
 4394 
 4395             if (exp.e1.op == TOK.symbolOffset && (cast(SymOffExp)exp.e1).hasOverloads)
 4396             {
 4397                 SymOffExp se = cast(SymOffExp)exp.e1;
 4398                 exp.e1 = new VarExp(se.loc, se.var, true);
 4399                 exp.e1 = exp.e1.expressionSemantic(sc);
 4400             }
 4401             else if (exp.e1.op == TOK.dot)
 4402             {
 4403                 DotExp de = cast(DotExp)exp.e1;
 4404 
 4405                 if (de.e2.op == TOK.overloadSet)
 4406                 {
 4407                     ethis = de.e1;
 4408                     tthis = de.e1.type;
 4409                     exp.e1 = de.e2;
 4410                 }
 4411             }
 4412             else if (exp.e1.op == TOK.star && exp.e1.type.ty == Tfunction)
 4413             {
 4414                 // Rewrite (*fp)(arguments) to fp(arguments)
 4415                 exp.e1 = (cast(PtrExp)exp.e1).e1;
 4416             }
 4417         }
 4418 
 4419         Type t1 = exp.e1.type ? exp.e1.type.toBasetype() : null;
 4420 
 4421         if (exp.e1.op == TOK.error)
 4422         {
 4423             result = exp.e1;
 4424             return;
 4425         }
 4426         if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))
 4427             return setError();
 4428 
 4429         // Check for call operator overload
 4430         if (t1)
 4431         {
 4432             if (t1.ty == Tstruct)
 4433             {
 4434                 auto sd = (cast(TypeStruct)t1).sym;
 4435                 sd.size(exp.loc); // Resolve forward references to construct object
 4436                 if (sd.sizeok != Sizeok.done)
 4437                     return setError();
 4438                 if (!sd.ctor)
 4439                     sd.ctor = sd.searchCtor();
 4440                 /* If `sd.ctor` is a generated copy constructor, this means that it
 4441                    is the single constructor that this struct has. In order to not
 4442                    disable default construction, the ctor is nullified. The side effect
 4443                    of this is that the generated copy constructor cannot be called
 4444                    explicitly, but that is ok, because when calling a constructor the
 4445                    default constructor should have priority over the generated copy
 4446                    constructor.
 4447                 */
 4448                 if (sd.ctor)
 4449                 {
 4450                     auto ctor = sd.ctor.isCtorDeclaration();
 4451                     if (ctor && ctor.isCpCtor && ctor.generated)
 4452                         sd.ctor = null;
 4453                 }
 4454 
 4455                 // First look for constructor
 4456                 if (exp.e1.op == TOK.type && sd.ctor)
 4457                 {
 4458                     if (!sd.noDefaultCtor && !(exp.arguments && exp.arguments.dim))
 4459                         goto Lx;
 4460 
 4461                     auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
 4462                     if (!sd.fill(exp.loc, sle.elements, true))
 4463                         return setError();
 4464                     if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))
 4465                         return setError();
 4466 
 4467                     // https://issues.dlang.org/show_bug.cgi?id=14556
 4468                     // Set concrete type to avoid further redundant semantic().
 4469                     sle.type = exp.e1.type;
 4470 
 4471                     /* Constructor takes a mutable object, so don't use
 4472                      * the immutable initializer symbol.
 4473                      */
 4474                     sle.useStaticInit = false;
 4475 
 4476                     Expression e = sle;
 4477                     if (auto cf = sd.ctor.isCtorDeclaration())
 4478                     {
 4479                         e = new DotVarExp(exp.loc, e, cf, true);
 4480                     }
 4481                     else if (auto td = sd.ctor.isTemplateDeclaration())
 4482                     {
 4483                         e = new DotIdExp(exp.loc, e, td.ident);
 4484                     }
 4485                     else if (auto os = sd.ctor.isOverloadSet())
 4486                     {
 4487                         e = new DotExp(exp.loc, e, new OverExp(exp.loc, os));
 4488                     }
 4489                     else
 4490                         assert(0);
 4491                     e = new CallExp(exp.loc, e, exp.arguments);
 4492                     e = e.expressionSemantic(sc);
 4493                     result = e;
 4494                     return;
 4495                 }
 4496                 // No constructor, look for overload of opCall
 4497                 if (search_function(sd, Id.call))
 4498                     goto L1;
 4499                 // overload of opCall, therefore it's a call
 4500                 if (exp.e1.op != TOK.type)
 4501                 {
 4502                     if (sd.aliasthis && exp.e1.type != exp.att1)
 4503                     {
 4504                         if (!exp.att1 && exp.e1.type.checkAliasThisRec())
 4505                             exp.att1 = exp.e1.type;
 4506                         exp.e1 = resolveAliasThis(sc, exp.e1);
 4507                         goto Lagain;
 4508                     }
 4509                     exp.error("%s `%s` does not overload ()", sd.kind(), sd.toChars());
 4510                     return setError();
 4511                 }
 4512 
 4513                 /* It's a struct literal
 4514                  */
 4515             Lx:
 4516                 Expression e = new StructLiteralExp(exp.loc, sd, exp.arguments, exp.e1.type);
 4517                 e = e.expressionSemantic(sc);
 4518                 result = e;
 4519                 return;
 4520             }
 4521             else if (t1.ty == Tclass)
 4522             {
 4523             L1:
 4524                 // Rewrite as e1.call(arguments)
 4525                 Expression e = new DotIdExp(exp.loc, exp.e1, Id.call);
 4526                 e = new CallExp(exp.loc, e, exp.arguments);
 4527                 e = e.expressionSemantic(sc);
 4528                 result = e;
 4529                 return;
 4530             }
 4531             else if (exp.e1.op == TOK.type && t1.isscalar())
 4532             {
 4533                 Expression e;
 4534 
 4535                 // Make sure to use the the enum type itself rather than its
 4536                 // base type
 4537                 // https://issues.dlang.org/show_bug.cgi?id=16346
 4538                 if (exp.e1.type.ty == Tenum)
 4539                 {
 4540                     t1 = exp.e1.type;
 4541                 }
 4542 
 4543                 if (!exp.arguments || exp.arguments.dim == 0)
 4544                 {
 4545                     e = t1.defaultInitLiteral(exp.loc);
 4546                 }
 4547                 else if (exp.arguments.dim == 1)
 4548                 {
 4549                     e = (*exp.arguments)[0];
 4550                     e = e.implicitCastTo(sc, t1);
 4551                     e = new CastExp(exp.loc, e, t1);
 4552                 }
 4553                 else
 4554                 {
 4555                     exp.error("more than one argument for construction of `%s`", t1.toChars());
 4556                     return setError();
 4557                 }
 4558                 e = e.expressionSemantic(sc);
 4559                 result = e;
 4560                 return;
 4561             }
 4562         }
 4563 
 4564         static FuncDeclaration resolveOverloadSet(Loc loc, Scope* sc,
 4565             OverloadSet os, Objects* tiargs, Type tthis, Expressions* arguments)
 4566         {
 4567             FuncDeclaration f = null;
 4568             foreach (s; os.a)
 4569             {
 4570                 if (tiargs && s.isFuncDeclaration())
 4571                     continue;
 4572                 if (auto f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, FuncResolveFlag.quiet))
 4573                 {
 4574                     if (f2.errors)
 4575                         return null;
 4576                     if (f)
 4577                     {
 4578                         /* Error if match in more than one overload set,
 4579                          * even if one is a 'better' match than the other.
 4580                          */
 4581                         ScopeDsymbol.multiplyDefined(loc, f, f2);
 4582                     }
 4583                     else
 4584                         f = f2;
 4585                 }
 4586             }
 4587             if (!f)
 4588                 .error(loc, "no overload matches for `%s`", os.toChars());
 4589             else if (f.errors)
 4590                 f = null;
 4591             return f;
 4592         }
 4593 
 4594         bool isSuper = false;
 4595         if (exp.e1.op == TOK.dotVariable && t1.ty == Tfunction || exp.e1.op == TOK.dotTemplateDeclaration)
 4596         {
 4597             UnaExp ue = cast(UnaExp)exp.e1;
 4598 
 4599             Expression ue1 = ue.e1;
 4600             Expression ue1old = ue1; // need for 'right this' check
 4601             VarDeclaration v;
 4602             if (ue1.op == TOK.variable && (v = (cast(VarExp)ue1).var.isVarDeclaration()) !is null && v.needThis())
 4603             {
 4604                 ue.e1 = new TypeExp(ue1.loc, ue1.type);
 4605                 ue1 = null;
 4606             }
 4607 
 4608             DotVarExp dve;
 4609             DotTemplateExp dte;
 4610             Dsymbol s;
 4611             if (exp.e1.op == TOK.dotVariable)
 4612             {
 4613                 dve = cast(DotVarExp)exp.e1;
 4614                 dte = null;
 4615                 s = dve.var;
 4616                 tiargs = null;
 4617             }
 4618             else
 4619             {
 4620                 dve = null;
 4621                 dte = cast(DotTemplateExp)exp.e1;
 4622                 s = dte.td;
 4623             }
 4624 
 4625             // Do overload resolution
 4626             exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, ue1 ? ue1.type : null, exp.arguments, FuncResolveFlag.standard);
 4627             if (!exp.f || exp.f.errors || exp.f.type.ty == Terror)
 4628                 return setError();
 4629 
 4630             if (exp.f.interfaceVirtual)
 4631             {
 4632                 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
 4633                  */
 4634                 auto b = exp.f.interfaceVirtual;
 4635                 auto ad2 = b.sym;
 4636                 ue.e1 = ue.e1.castTo(sc, ad2.type.addMod(ue.e1.type.mod));
 4637                 ue.e1 = ue.e1.expressionSemantic(sc);
 4638                 ue1 = ue.e1;
 4639                 auto vi = exp.f.findVtblIndex(&ad2.vtbl, cast(int)ad2.vtbl.dim);
 4640                 assert(vi >= 0);
 4641                 exp.f = ad2.vtbl[vi].isFuncDeclaration();
 4642                 assert(exp.f);
 4643             }
 4644             if (exp.f.needThis())
 4645             {
 4646                 AggregateDeclaration ad = exp.f.toParentLocal().isAggregateDeclaration();
 4647                 ue.e1 = getRightThis(exp.loc, sc, ad, ue.e1, exp.f);
 4648                 if (ue.e1.op == TOK.error)
 4649                 {
 4650                     result = ue.e1;
 4651                     return;
 4652                 }
 4653                 ethis = ue.e1;
 4654                 tthis = ue.e1.type;
 4655                 if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isScopeQual))
 4656                 {
 4657                     if (global.params.vsafe && checkParamArgumentEscape(sc, exp.f, null, ethis, false, false))
 4658                         return setError();
 4659                 }
 4660             }
 4661 
 4662             /* Cannot call public functions from inside invariant
 4663              * (because then the invariant would have infinite recursion)
 4664              */
 4665             if (sc.func && sc.func.isInvariantDeclaration() && ue.e1.op == TOK.this_ && exp.f.addPostInvariant())
 4666             {
 4667                 exp.error("cannot call `public`/`export` function `%s` from invariant", exp.f.toChars());
 4668                 return setError();
 4669             }
 4670 
 4671             checkFunctionAttributes(exp, sc, exp.f);
 4672             checkAccess(exp.loc, sc, ue.e1, exp.f);
 4673             if (!exp.f.needThis())
 4674             {
 4675                 exp.e1 = Expression.combine(ue.e1, new VarExp(exp.loc, exp.f, false));
 4676             }
 4677             else
 4678             {
 4679                 if (ue1old.checkRightThis(sc))
 4680                     return setError();
 4681                 if (exp.e1.op == TOK.dotVariable)
 4682                 {
 4683                     dve.var = exp.f;
 4684                     exp.e1.type = exp.f.type;
 4685                 }
 4686                 else
 4687                 {
 4688                     exp.e1 = new DotVarExp(exp.loc, dte.e1, exp.f, false);
 4689                     exp.e1 = exp.e1.expressionSemantic(sc);
 4690                     if (exp.e1.op == TOK.error)
 4691                         return setError();
 4692                     ue = cast(UnaExp)exp.e1;
 4693                 }
 4694                 version (none)
 4695                 {
 4696                     printf("ue.e1 = %s\n", ue.e1.toChars());
 4697                     printf("f = %s\n", exp.f.toChars());
 4698                     printf("t1 = %s\n", t1.toChars());
 4699                     printf("e1 = %s\n", exp.e1.toChars());
 4700                     printf("e1.type = %s\n", exp.e1.type.toChars());
 4701                 }
 4702 
 4703                 // See if we need to adjust the 'this' pointer
 4704                 AggregateDeclaration ad = exp.f.isThis();
 4705                 ClassDeclaration cd = ue.e1.type.isClassHandle();
 4706                 if (ad && cd && ad.isClassDeclaration())
 4707                 {
 4708                     if (ue.e1.op == TOK.dotType)
 4709                     {
 4710                         ue.e1 = (cast(DotTypeExp)ue.e1).e1;
 4711                         exp.directcall = true;
 4712                     }
 4713                     else if (ue.e1.op == TOK.super_)
 4714                         exp.directcall = true;
 4715                     else if ((cd.storage_class & STC.final_) != 0) // https://issues.dlang.org/show_bug.cgi?id=14211
 4716                         exp.directcall = true;
 4717 
 4718                     if (ad != cd)
 4719                     {
 4720                         ue.e1 = ue.e1.castTo(sc, ad.type.addMod(ue.e1.type.mod));
 4721                         ue.e1 = ue.e1.expressionSemantic(sc);
 4722                     }
 4723                 }
 4724             }
 4725             // If we've got a pointer to a function then deference it
 4726             // https://issues.dlang.org/show_bug.cgi?id=16483
 4727             if (exp.e1.type.ty == Tpointer && exp.e1.type.nextOf().ty == Tfunction)
 4728             {
 4729                 Expression e = new PtrExp(exp.loc, exp.e1);
 4730                 e.type = exp.e1.type.nextOf();
 4731                 exp.e1 = e;
 4732             }
 4733             t1 = exp.e1.type;
 4734         }
 4735         else if (exp.e1.op == TOK.super_ || exp.e1.op == TOK.this_)
 4736         {
 4737             auto ad = sc.func ? sc.func.isThis() : null;
 4738             auto cd = ad ? ad.isClassDeclaration() : null;
 4739 
 4740             isSuper = exp.e1.op == TOK.super_;
 4741             if (isSuper)
 4742             {
 4743                 // Base class constructor call
 4744                 if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())
 4745                 {
 4746                     exp.error("super class constructor call must be in a constructor");
 4747                     return setError();
 4748                 }
 4749                 if (!cd.baseClass.ctor)
 4750                 {
 4751                     exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
 4752                     return setError();
 4753                 }
 4754             }
 4755             else
 4756             {
 4757                 // `this` call expression must be inside a
 4758                 // constructor
 4759                 if (!ad || !sc.func.isCtorDeclaration())
 4760                 {
 4761                     exp.error("constructor call must be in a constructor");
 4762                     return setError();
 4763                 }
 4764 
 4765                 // https://issues.dlang.org/show_bug.cgi?id=18719
 4766                 // If `exp` is a call expression to another constructor
 4767                 // then it means that all struct/class fields will be
 4768                 // initialized after this call.
 4769                 foreach (ref field; sc.ctorflow.fieldinit)
 4770                 {
 4771                     field.csx |= CSX.this_ctor;
 4772                 }
 4773             }
 4774 
 4775             if (!sc.intypeof && !(sc.ctorflow.callSuper & CSX.halt))
 4776             {
 4777                 if (sc.inLoop || sc.ctorflow.callSuper & CSX.label)
 4778                     exp.error("constructor calls not allowed in loops or after labels");
 4779                 if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor))
 4780                     exp.error("multiple constructor calls");
 4781                 if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor))
 4782                     exp.error("an earlier `return` statement skips constructor");
 4783                 sc.ctorflow.callSuper |= CSX.any_ctor | (isSuper ? CSX.super_ctor : CSX.this_ctor);
 4784             }
 4785 
 4786             tthis = ad.type.addMod(sc.func.type.mod);
 4787             auto ctor = isSuper ? cd.baseClass.ctor : ad.ctor;
 4788             if (auto os = ctor.isOverloadSet())
 4789                 exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);
 4790             else
 4791                 exp.f = resolveFuncCall(exp.loc, sc, ctor, null, tthis, exp.arguments, FuncResolveFlag.standard);
 4792 
 4793             if (!exp.f || exp.f.errors)
 4794                 return setError();
 4795 
 4796             checkFunctionAttributes(exp, sc, exp.f);
 4797             checkAccess(exp.loc, sc, null, exp.f);
 4798 
 4799             exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);
 4800             exp.e1 = exp.e1.expressionSemantic(sc);
 4801             // https://issues.dlang.org/show_bug.cgi?id=21095
 4802             if (exp.e1.op == TOK.error)
 4803                 return setError();
 4804             t1 = exp.e1.type;
 4805 
 4806             // BUG: this should really be done by checking the static
 4807             // call graph
 4808             if (exp.f == sc.func)
 4809             {
 4810                 exp.error("cyclic constructor call");
 4811                 return setError();
 4812             }
 4813         }
 4814         else if (exp.e1.op == TOK.overloadSet)
 4815         {
 4816             auto os = (cast(OverExp)exp.e1).vars;
 4817             exp.f = resolveOverloadSet(exp.loc, sc, os, tiargs, tthis, exp.arguments);
 4818             if (!exp.f)
 4819                 return setError();
 4820             if (ethis)
 4821                 exp.e1 = new DotVarExp(exp.loc, ethis, exp.f, false);
 4822             else
 4823                 exp.e1 = new VarExp(exp.loc, exp.f, false);
 4824             goto Lagain;
 4825         }
 4826         else if (!t1)
 4827         {
 4828             exp.error("function expected before `()`, not `%s`", exp.e1.toChars());
 4829             return setError();
 4830         }
 4831         else if (t1.ty == Terror)
 4832         {
 4833             return setError();
 4834         }
 4835         else if (t1.ty != Tfunction)
 4836         {
 4837             TypeFunction tf;
 4838             const(char)* p;
 4839             Dsymbol s;
 4840             exp.f = null;
 4841             if (exp.e1.op == TOK.function_)
 4842             {
 4843                 // function literal that direct called is always inferred.
 4844                 assert((cast(FuncExp)exp.e1).fd);
 4845                 exp.f = (cast(FuncExp)exp.e1).fd;
 4846                 tf = cast(TypeFunction)exp.f.type;
 4847                 p = "function literal";
 4848             }
 4849             else if (t1.ty == Tdelegate)
 4850             {
 4851                 TypeDelegate td = cast(TypeDelegate)t1;
 4852                 assert(td.next.ty == Tfunction);
 4853                 tf = cast(TypeFunction)td.next;
 4854                 p = "delegate";
 4855             }
 4856             else if (t1.ty == Tpointer && (cast(TypePointer)t1).next.ty == Tfunction)
 4857             {
 4858                 tf = cast(TypeFunction)(cast(TypePointer)t1).next;
 4859                 p = "function pointer";
 4860             }
 4861             else if (exp.e1.op == TOK.dotVariable && (cast(DotVarExp)exp.e1).var.isOverDeclaration())
 4862             {
 4863                 DotVarExp dve = cast(DotVarExp)exp.e1;
 4864                 exp.f = resolveFuncCall(exp.loc, sc, dve.var, tiargs, dve.e1.type, exp.arguments, FuncResolveFlag.overloadOnly);
 4865                 if (!exp.f)
 4866                     return setError();
 4867                 if (exp.f.needThis())
 4868                 {
 4869                     dve.var = exp.f;
 4870                     dve.type = exp.f.type;
 4871                     dve.hasOverloads = false;
 4872                     goto Lagain;
 4873                 }
 4874                 exp.e1 = new VarExp(dve.loc, exp.f, false);
 4875                 Expression e = new CommaExp(exp.loc, dve.e1, exp);
 4876                 result = e.expressionSemantic(sc);
 4877                 return;
 4878             }
 4879             else if (exp.e1.op == TOK.variable && (cast(VarExp)exp.e1).var.isOverDeclaration())
 4880             {
 4881                 s = (cast(VarExp)exp.e1).var;
 4882                 goto L2;
 4883             }
 4884             else if (exp.e1.op == TOK.template_)
 4885             {
 4886                 s = (cast(TemplateExp)exp.e1).td;
 4887             L2:
 4888                 exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.arguments, FuncResolveFlag.standard);
 4889                 if (!exp.f || exp.f.errors)
 4890                     return setError();
 4891                 if (exp.f.needThis())
 4892                 {
 4893                     if (hasThis(sc))
 4894                     {
 4895                         // Supply an implicit 'this', as in
 4896                         //    this.ident
 4897                         exp.e1 = new DotVarExp(exp.loc, (new ThisExp(exp.loc)).expressionSemantic(sc), exp.f, false);
 4898                         goto Lagain;
 4899                     }
 4900                     else if (isNeedThisScope(sc, exp.f))
 4901                     {
 4902                         exp.error("need `this` for `%s` of type `%s`", exp.f.toChars(), exp.f.type.toChars());
 4903                         return setError();
 4904                     }
 4905                 }
 4906                 exp.e1 = new VarExp(exp.e1.loc, exp.f, false);
 4907                 goto Lagain;
 4908             }
 4909             else
 4910             {
 4911                 exp.error("function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars());
 4912                 return setError();
 4913             }
 4914 
 4915             const(char)* failMessage;
 4916             Expression[] fargs = exp.arguments ? (*exp.arguments)[] : null;
 4917             if (!tf.callMatch(null, fargs, 0, &failMessage, sc))
 4918             {
 4919                 OutBuffer buf;
 4920                 buf.writeByte('(');
 4921                 argExpTypesToCBuffer(&buf, exp.arguments);
 4922                 buf.writeByte(')');
 4923                 if (tthis)
 4924                     tthis.modToBuffer(&buf);
 4925 
 4926                 //printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
 4927                 .error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
 4928                     p, exp.e1.toChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
 4929                 if (failMessage)
 4930                     errorSupplemental(exp.loc, "%s", failMessage);
 4931                 return setError();
 4932             }
 4933             // Purity and safety check should run after testing arguments matching
 4934             if (exp.f)
 4935             {
 4936                 exp.checkPurity(sc, exp.f);
 4937                 exp.checkSafety(sc, exp.f);
 4938                 exp.checkNogc(sc, exp.f);
 4939                 if (exp.f.checkNestedReference(sc, exp.loc))
 4940                     return setError();
 4941             }
 4942             else if (sc.func && sc.intypeof != 1 && !(sc.flags & (SCOPE.ctfe | SCOPE.debug_)))
 4943             {
 4944                 bool err = false;
 4945                 if (!tf.purity && sc.func.setImpure())
 4946                 {
 4947                     exp.error("`pure` %s `%s` cannot call impure %s `%s`",
 4948                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
 4949                     err = true;
 4950                 }
 4951                 if (!tf.isnogc && sc.func.setGC())
 4952                 {
 4953                     exp.error("`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
 4954                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
 4955                     err = true;
 4956                 }
 4957                 if (tf.trust <= TRUST.system && sc.func.setUnsafe())
 4958                 {
 4959                     exp.error("`@safe` %s `%s` cannot call `@system` %s `%s`",
 4960                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
 4961                     err = true;
 4962                 }
 4963                 if (err)
 4964                     return setError();
 4965             }
 4966 
 4967             if (t1.ty == Tpointer)
 4968             {
 4969                 Expression e = new PtrExp(exp.loc, exp.e1);
 4970                 e.type = tf;
 4971                 exp.e1 = e;
 4972             }
 4973             t1 = tf;
 4974         }
 4975         else if (exp.e1.op == TOK.variable)
 4976         {
 4977             // Do overload resolution
 4978             VarExp ve = cast(VarExp)exp.e1;
 4979 
 4980             exp.f = ve.var.isFuncDeclaration();
 4981             assert(exp