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