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