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